-
Notifications
You must be signed in to change notification settings - Fork 4
/
Math.ark
191 lines (171 loc) · 5.86 KB
/
Math.ark
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# @brief Return the absolute value of a number
# @param _x the number to get the absolute value of
# @author https://github.com/rstefanic
(let math:abs (fun (_x)
(if (< _x 0)
(* -1 _x)
_x)))
# @brief Return true if the number is even, false otherwise
# @param _n the number
# @author https://github.com/rstefanic
(let math:even (fun (_n) (= 0 (mod _n 2))))
# @brief Return true if the number is odd, false otherwise
# @param _n the number
# @author https://github.com/rstefanic
(let math:odd (fun (_n) (= 1 (math:abs (mod _n 2)))))
# @brief Get the minimum between two numbers
# @param _a the first number
# @param _b the second number
# @author https://github.com/rstefanic
(let math:min (fun (_a _b)
(if (< _a _b)
_a
_b)))
# @brief Get the maximum between two numbers
# @param _a the first number
# @param _b the second number
# @author https://github.com/rstefanic
(let math:max (fun (_a _b)
(if (> _a _b)
_a
_b)))
# @brief Get a number to a given power
# @details Note that it's defined as exp(a * ln(x)), thus won't work for negative numbers
# @param _x the number to pow
# @param _a the exponent
# @author https://github.com/SuperFola
(let math:pow (fun (_x _a) (math:exp (* _a (math:ln _x)))))
# @brief Get the square root of a number
# @details Square roots can't be taken for negative numbers for obvious reasons.
# @param _x the number
# @author https://github.com/SuperFola
(let math:sqrt (fun (_x) (math:exp (* 0.5 (math:ln _x)))))
# @brief Run the fibonacci function on a number
# @param n the number
# @author https://github.com/SuperFola
# =begin
# (math:fibo 45 0 1)
# =end
(let math:fibo (fun (n) {
(let impl (fun (n p c)
(if (<= n 0)
0
(if (= n 1)
c
(impl (- n 1) c (+ p c))))))
(impl n 0 1) }))
# @brief Returns the list of a number's divisors
# @param n the number
# @author https://github.com/Wafelack
# =begin
# (math:divs 6) # Returns [1 2 3 6]
# =end
(let math:divs (fun (n) {
(assert (>= n 2) "math:divs: n must be greater or equal to 2")
(mut i 2)
(mut divisors [1])
(let top (math:ceil (/ n 2)))
(while (and (<= i top) (!= top n)) {
(if (= (mod n i) 0)
(set divisors (append divisors i)))
(set i (+ i 1)) })
(append divisors n) }))
# @brief Returns the logarithm base n of a number
# @param x the number
# @param n the base
# @author https://github.com/Gryfenfer97
# =begin
# (math:log 81 3) # Returns 4
# =end
(let math:log (fun (x n) {
(assert (> x 0) "math:log: x must be greater than 0")
(assert (>= n 1) "math:log: n must be greater or equal to 1")
(math:round (/ (math:ln x) (math:ln n))) }))
# @brief Returns the logarithm base 2 of a number
# @param x the number
# @author https://github.com/Gryfenfer97
# =begin
# (math:log2 128) # Returns 7
# =end
(let math:log2 (fun (x) (math:log x 2)))
# @brief Returns the logarithm base 10 of a number
# @param x the number
# @author https://github.com/Gryfenfer97
# =begin
# (math:log10 1000) # Returns 3
# =end
(let math:log10 (fun (x) (math:log x 10)))
# @brief Returns the quotient of the euclidian division of a and b
# @param a the dividend
# @param b the divisor
# @author https://github.com/fabien-zoccola
# =begin
# (math:floordiv 14 6) # Returns 2
# =end
(let math:floordiv (fun (a b) (math:floor (/ a b))))
# @brief Create a complex number
# @param real the real part of the complex number
# @param imag the imaginary value
# =begin
# (let c (math:complex 1 2))
# (print c.real " " c.imag) # 1 2
# =end
# @author https://github.com/SuperFola
(let math:complex (fun (real imag)
(fun (&real &imag) ())))
# @brief Compute the addition of two complex number
# @param _c0 the first complex number
# @param _c1 the second complex number
# =begin
# (let c (math:complex-add (math:complex 1 2) (math:complex 3 4)))
# (print c.real " " c.imag) # 4 6
# =end
# @author https://github.com/SuperFola
(let math:complex-add (fun (_c0 _c1) (math:complex (+ _c0.real _c1.real) (+ _c0.imag _c1.imag))))
# @brief Compute the substraction of two complex number
# @param _c0 the first complex number
# @param _c1 the second complex number
# =begin
# (let c (math:complex-sub (math:complex 1 2) (math:complex 3 4)))
# (print c.real " " c.imag) # -2 -2
# =end
# @author https://github.com/SuperFola
(let math:complex-sub (fun (_c0 _c1) (math:complex (- _c0.real _c1.real) (- _c0.imag _c1.imag))))
# @brief Compute the multiplication of two complex number
# @param _c0 the first complex number
# @param _c1 the second complex number
# =begin
# (let c (math:complex-mul (math:complex 1 2) (math:complex 3 4)))
# (print c.real " " c.imag) # -5 10
# =end
# @author https://github.com/SuperFola
(let math:complex-mul (fun (_c0 _c1) (math:complex (+ (* _c0.real _c1.real) (- 0 (* _c0.imag _c1.imag))) (+ (* _c0.real _c1.imag) (* _c1.real _c0.imag)))))
# @brief Compute the conjugate of a complex number
# @param _c the complex number
# =begin
# (let c (math:complex-conjugate (math:complex 1 2)))
# (print c.real " " c.imag) # 1 -2
# =end
# @author https://github.com/SuperFola
(let math:complex-conjugate (fun (_c) (math:complex _c.real (- 0 _c.imag))))
# @brief Compute the module of a complex number
# @param _c the complex number
# =begin
# (let c (math:complex-module (math:complex 1 2)))
# (print c) # 2.2360679774997896964...
# =end
# @author https://github.com/SuperFola
(let math:complex-module (fun (_c) (math:sqrt (+ (* _c.real _c.real) (* _c.imag _c.imag)))))
# @brief Compute the division of two complex number
# @param _c0 the first complex number
# @param _c1 the second complex number
# =begin
# (let c (math:complex-div (math:complex 1 2) (math:complex 3 4)))
# (print c.real " " c.imag) # 0.44 0.08
# =end
# @author https://github.com/SuperFola
(let math:complex-div (fun (_c0 _c1) {
(let _conj (math:complex-conjugate _c1))
(let _top (math:complex-mul _c0 _conj))
(let _denom (+ (* _c1.real _c1.real) (* _c1.imag _c1.imag)))
(math:complex (/ _top.real _denom) (/ _top.imag _denom)) }))