forked from thenumbernine/lua-ext
-
Notifications
You must be signed in to change notification settings - Fork 0
/
math.lua
149 lines (126 loc) · 2.85 KB
/
math.lua
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
local math = {}
for k,v in pairs(require 'math') do math[k] = v end
math.nan = 0/0
math.e = math.exp(1)
-- luajit and lua 5.1 compat ...
if not math.atan2 then math.atan2 = math.atan end
-- also note, code that uses math.atan(y,x) in luajit will instead just call math.atan(y) ...
-- some luas don't have hyperbolic trigonometric functions
if not math.sinh then
function math.sinh(x)
local ex = math.exp(x)
return .5 * (ex - 1/ex)
end
end
if not math.cosh then
function math.cosh(x)
local ex = math.exp(x)
return .5 * (ex + 1/ex)
end
end
if not math.tanh then
function math.tanh(x)
--[[ this isn't so stable.
local ex = math.exp(x)
return (ex - 1/ex) / (ex + 1/ex)
--]]
-- [[ instead...
-- if e^-2x < smallest float epsilon
-- then consider (e^x - e^-x) ~ e^x .. well, it turns out to be 1
-- and if e^2x < smallest float epsilon then -1
if x < 0 then
local e2x = math.exp(2*x)
return (e2x - 1) / (e2x + 1)
else
local em2x = math.exp(-2*x)
return (1 - em2x) / (1 + em2x)
end
--]]
end
end
function math.asinh(x)
return math.log(x + math.sqrt(x*x + 1))
end
function math.acosh(x)
return math.log(x + math.sqrt(x*x - 1))
end
function math.atanh(x)
return .5 * math.log((1 + x) / (1 - x))
end
function math.cbrt(x)
return math.sign(x) * math.abs(x)^(1/3)
end
function math.clamp(v,min,max)
return math.min(math.max(v,min), max)
end
function math.sign(x)
if x < 0 then return -1 end
if x > 0 then return 1 end
return 0
end
function math.trunc(x)
if x < 0 then return math.ceil(x) else return math.floor(x) end
end
function math.round(x)
return math.floor(x+.5)
end
function math.isnan(x) return x ~= x end
function math.isinf(x) return x == math.huge or x == -math.huge end
function math.isfinite(x) return tonumber(x) and not math.isnan(x) and not math.isinf(x) end
function math.isprime(n)
if n < 2 then return false end -- 1 isnt prime
for i=2,math.floor(math.sqrt(n)) do
if n%i == 0 then
return false
end
end
return true
end
-- assumes n is a non-negative integer. this isn't the Gamma function
function math.factorial(n)
local prod = 1
for i=1,n do
prod = prod * i
end
return prod
end
function math.factors(n)
local table = require 'ext.table'
local f = table()
for i=1,n do
if n%i == 0 then
f:insert(i)
end
end
return f
end
-- returns a table containing the prime factorization of the number
function math.primeFactorization(n)
local table = require 'ext.table'
n = math.floor(n)
local f = table()
while n > 1 do
local found = false
for i=2,math.floor(math.sqrt(n)) do
if n%i == 0 then
n = math.floor(n/i)
f:insert(i)
found = true
break
end
end
if not found then
f:insert(n)
break
end
end
return f
end
function math.gcd(a,b)
return b == 0 and a or math.gcd(b, a % b)
end
-- if this math lib gets too big ...
function math.mix(a,b,s)
return a * (1 - s) + b * s
end
return math