Now, this may seem really simple at first, the ln(x) given x so math.log(x) and done, sadly no.
What I’m asking for is a function for getting the ln(x), currently I’ve tried 2 methods, 1 of which is far more accurate than the other, but still has a small margin of error.
Summation Solution
The first uses a summation (here’s the function I’ve made for that, disregard the path),
note: calc.math.e = e (2.71828182845904523536)
function calc.series.summation.new(s,n,body,...) local self = {} self.s = s -- initial step self.n = n -- step amount = n-s self.body = body -- body function to occur to i,... within every step self.args = {...} self.p = 0 function self:update() local p = 0 for i=self.s,self.n,1 do p = p + self.body(i,unpack(self.args)) end self.p = p end self:update() function self:setargs(...) self.args = {...} end function self:setbody(newbody) self.body = newbody end return self end
Then, the function for getting the ln of a given x is as follows,
function calc.math.ln(x)
local summation = calc.series.summation.new(1,100000,function(n) return ((1/n)*(((x-1)/x)^n)) end)
summation:update()
return summation.p
end
This is great and all, but once you increase to the higher values of x (like e^20 being x), it doesn’t work and it gives a value which is wrong by a large degree. The solution to this would be changing the 100000 in the summation to a higher number, but this will just create a loop being called 100000+ times (which the 100000 is already alot). The solution for this was to create a whole new function for integrals.
Integral Solution
The function for integrals is as follows,
function calc.series.integral.new(a,dx,fx,s,fp) -- work in progress // DO NOT USE
local self = {}
self.fx = fx -- f(x) = y = fx
self.fp = fp or function(p) return p end
self.dx = dx or 1/100
self.a = a
self.s = s or 1
self.p = 0
function self:update()
local p = 0
for x=self.s,self.a,dx do
p = p + self.fx(x,dx)
end
self.p = self.fp(p)
end
self:update()
function self:setargs(...)
self.args = {...}
end
function self:setbody(newbody)
self.body = newbody
end
return self
end
Now, using this we can create a function for the ln(a) which is as follows,
function calc.math.ln(a)
local es = 0
repeat es = es+1 until (calc.math.e^es)>a;
if a == calc.math.e^(es-1) then -- incase it is e, don't overshoot based on algorithm
return es-1
end
local integral = calc.series.integral.new(
a, -- a
(calc.math.e^(es))/1500, -- step
function(x,dx) return ((1/x)*dx) end, -- f(x) = y
calc.math.e^(es-1), -- starting step
function(p) return p+(es-1) end -- f(p) = integral.p given p
)
integral:update()
return integral.p
end
The only problem with this is that it has to use a loop of 1500 and then fetches a really close value for the ln(a) with a margin of error of 0.002 (which can be reduced by changing the step/dx size) along with the fact that it can lag the first time you use it.
With all the above issues, comments and functions being stated, is there a better way to be doing this? Or are these the best methods to use?
Thank you for reading this far, if you have any questions as to how anything works, or have any comments or replies, please respond below. I will try to reply as quickly as possible.
Thanks,
Scar