(.module: {#.doc "Common mathematical constants and functions."} [lux #* [tool [compiler ["." host]]]]) (template [ ] [(def: #export {#.doc } Frac )] [e +2.7182818284590452354 "The base of the natural logarithm."] [pi +3.14159265358979323846 "The ratio of a circle's circumference to its diameter."] [tau +6.28318530717958647692 "The ratio of a circle's circumference to its radius."] ) (`` (for {(~~ (static host.old)) (as-is (template [ ] [(def: #export ( input) (-> Frac Frac) ( input))] [cos "jvm invokestatic:java.lang.Math:cos:double"] [sin "jvm invokestatic:java.lang.Math:sin:double"] [tan "jvm invokestatic:java.lang.Math:tan:double"] [acos "jvm invokestatic:java.lang.Math:acos:double"] [asin "jvm invokestatic:java.lang.Math:asin:double"] [atan "jvm invokestatic:java.lang.Math:atan:double"] [exp "jvm invokestatic:java.lang.Math:exp:double"] [log "jvm invokestatic:java.lang.Math:log:double"] [ceil "jvm invokestatic:java.lang.Math:ceil:double"] [floor "jvm invokestatic:java.lang.Math:floor:double"] ) (def: #export (pow param subject) (-> Frac Frac Frac) ("jvm invokestatic:java.lang.Math:pow:double,double" subject param))) (~~ (static host.jvm)) (as-is (template: (!double value) (|> value (:coerce (primitive "java.lang.Double")) "jvm object cast")) (template: (!frac value) (|> value "jvm object cast" (: (primitive "java.lang.Double")) (:coerce Frac))) (template [ ] [(def: #export (-> Frac Frac) (|>> !double ["double"] ("jvm member invoke static" "java.lang.Math" ) !frac))] [cos "cos"] [sin "sin"] [tan "tan"] [acos "acos"] [asin "asin"] [atan "atan"] [exp "exp"] [log "log"] [ceil "ceil"] [floor "floor"] ) (def: #export (pow param subject) (-> Frac Frac Frac) (|> ("jvm member invoke static" "java.lang.Math" "pow" ["double" (!double subject)] ["double" (!double param)]) !frac)))})) (def: #export (round input) (-> Frac Frac) (let [floored (floor input) diff (f/- floored input)] (cond (f/> +0.5 diff) (f/+ +1.0 floored) (f/< -0.5 diff) (f/+ -1.0 floored) ## else floored))) (def: #export (atan2 param subject) (-> Frac Frac Frac) (cond (f/> +0.0 param) (atan (f// param subject)) (f/< +0.0 param) (if (f/>= +0.0 subject) (|> subject (f// param) atan (f/+ pi)) (|> subject (f// param) atan (f/- pi))) ## (f/= +0.0 param) (cond (f/> +0.0 subject) (|> pi (f// +2.0)) (f/< +0.0 subject) (|> pi (f// -2.0)) ## (f/= +0.0 subject) (f// +0.0 +0.0)))) (def: #export (log' base input) (-> Frac Frac Frac) (f// (log base) (log input))) (def: #export (factorial n) (-> Nat Nat) (loop [acc 1 n n] (if (n/<= 1 n) acc (recur (n/* n acc) (dec n))))) (def: #export (hypotenuse catA catB) (-> Frac Frac Frac) (pow +0.5 (f/+ (pow +2.0 catA) (pow +2.0 catB)))) (template [ <*> <->] [(def: #export ( a b) {#.doc "Greatest Common Divisor."} (-> ) (case b a _ ( b ( b a)))) (def: #export ( a b) {#.doc "Least Common Multiple."} (-> ) (case [a b] (^or [_ ] [ _]) _ (|> a ( ( a b)) (<*> b)) ))] [Nat n/mod n/gcd n/lcm 0 n/* n// n/-] [Int i/mod i/gcd i/lcm +0 i/* i// i/-] ) ## Hyperbolic functions ## https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions (template [ ] [(def: #export ( x) (-> Frac Frac) (|> (exp x) ( (exp (f/* -1.0 x))) (f// +2.0))) (def: #export ( x) (-> Frac Frac) (|> +2.0 (f// (|> (exp x) ( (exp (f/* -1.0 x)))))))] [sinh f/- csch] [cosh f/+ sech] ) (template [ ] [(def: #export ( x) (-> Frac Frac) (let [e+ (exp x) e- (exp (f/* -1.0 x)) sinh' (|> e+ (f/- e-)) cosh' (|> e+ (f/+ e-))] (|> (f// ))))] [tanh sinh' cosh'] [coth cosh' sinh'] ) ## https://en.wikipedia.org/wiki/Inverse_hyperbolic_functions#Definitions_in_terms_of_logarithms (template [ ] [(def: #export ( x) (-> Frac Frac) (|> x (pow +2.0) ( +1.0) (pow +0.5) (f/+ x) log))] [asinh f/+] [acosh f/-] ) (template [ ] [(def: #export ( x) (-> Frac Frac) (let [x+ (|> (f/+ )) x- (|> (f/- ))] (|> x+ (f// x-) log (f// +2.0))))] [atanh +1.0 x] [acoth x +1.0] ) (template [ ] [(def: #export ( x) (-> Frac Frac) (let [x^2 (|> x (pow +2.0))] (|> +1.0 ( x^2) (pow +0.5) (f/+ +1.0) (f// x) log)))] [asech f/-] [acsch f/+] )