The following is the code of my function
function myfunction ( ... )
local tbl = table.pack(...)
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slight modification.')
return
end
end
if some condition then
**recursive call to myfunction**
else
some result
end
end
The function works fine and it gives expected results to me. But the problem as one can observe that function is calling itself in recursive manner. So the first part of the code which I am giving below also gets repeated several times during each recursive call. Obviously I want to check input only once and exit the function if it is incorrect. If input is correct, then it should not be checked every recursive call. So how the code can be optimized for this purpose. Can some value be assigned to global variable and then use it somewhere inside the function (in if else condition) to avoid repetition. But again the check for value will get repeat (though it is less costly compared to the current approach. The problem is to avoid repetition of the following code (which is part of above code).
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slightly modified')
return
end
end
As an example, consider the following function.
function factorial(n)
if (n == 0) then
return 1
else
return n * factorial(n - 1)
end
end
When factorial(9.3) is executed it results into stack overflow as no error input check is involved. To handle this the following error mechanism is added.
function factorialwithinputcheck(n)
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * factorialwithinputcheck(n-1)
end
end
This function gives error and stops execution whenever input is incorrect. The factorialwithinputcheck(9.3) doesn't result into stack overflow. But again the input check is made in every recursive call. How this code for example can be optimised?
Being more specific as in my comment, I'd propose something like this:
function _factorial(n)
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
function factorialwithinputcheck(n)
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
or hiding _factorial:
function factorialwithinputcheck(n)
local function _factorial(n)
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
but again, I'm not completely sure if this way the _factorial function has to be "created" multiple times (which should have a performance impact as well). But maybe this can be figured out with some benchmarking.
EDIT: Oh and if you want some input sanitizing: Up to now, you don't check for negative numbers.
Edit2: And since you ask for general optimization of your factorial function. Yes of course one could convert the recursive procedure into an iterative one (avoiding creating new stack frames that many times).
Using some sort of accumulator (acc) passing n*acc down to the next call, you could alternatively make the function tail recursive, (according to this pil chapter (I hope there is no change in that in more frequent lua verions) lua will then handle this for you).
For example:
local function factorial_rec(n)
local function _factorial(n)
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * _factorial(n-1)
end
end
(but to be honest I don't see much of a performance boost with this (0.000293s vs 0.000354s if I loop over factorial form 0 to 40, numbers starting with 21! are already beyond the range for numbers in lua (for my installation), checked only with a very rudimentary benchmark))
Related
I am Julia user.
I want to define a function whose output is a function.
This is an example.
function get_f(p::Int)
if p == 1
return f(x) = x^2
else
return f(x) = cos(x)
return f
end
But it does not work!
f(x) = get_f(2)
f(2)
# UndefVarError x not defined.
Also, when I run the code, we have the following WARNING.
WARNING: Method definition f(Int64) in module Main at REPL[88]:4
What is the problem? If you know another good way, please tell me.
I guess we can write more sophisticated code using 'struct', but I don't know how.
We should use anonymous functions.
function get_f(p::Int)
if p == 1
return (x,y) -> x+y
elseif p == 2
return (x,y) -> norm(x-y)
else
return (x,y) -> x*y
end
end
f = get_f(2)
f(3,2) # 1.0
It works!
My math may not be serving me well. I've written a simple recursive function in Verilog to calculate value of log base 2. Log2(1000) should return 9.965 rounded to 10. But, my simulation shows that the function returns 9 as the final value of the recursive function. Any idea what I'm doing wrong?
module test;
real numBits;
function real log2 (input int X);
if (X == 1)
log2 = 0.0;
else begin
log2 = log2(X / 2) + 1.0;
$display($stime,,,"log2 = %0d",log2);
end
endfunction
initial begin
numBits = log2(1000);
$display($stime,,,"numBits = %f",numBits);
end
endmodule
Here's the EDA playground link that shows the code:
https://www.edaplayground.com/x/icx7
A couple of problems with your code. The first is the input to your function needs to be real. Then, it's never good to compare real numbers with equality do to rounding errors. Use X<=1 instead. And finally you should declare recursive functions with an automatic lifetime so that the arguments and the return values do not get overwritten.
function automatic real log2 (input real X);
if (X <= 1)
log2 = 0.0;
else begin
log2 = log2(X / 2) + 1.0;
$display($stime,,,"log2 = %0g",log2);
end
endfunction
I'm currently learning about recursion, it's pretty hard to understand. I found a very common example for it:
function factorial(N)
local Value
if N == 0 then
Value = 1
else
Value = N * factorial(N - 1)
end
return Value
end
print(factorial(3))
N == 0 is the base case. But when i changed it into N == 1, the result is still remains the same. (it will print 6).
Is using the base case important? (will it break or something?)
What's the difference between using N == 0 (base case) and N == 1?
That's just a coincidence, since 1 * 1 = 1, so it ends up working either way.
But consider the edge-case where N = 0, if you check for N == 1, then you'd go into the else branch and calculate 0 * factorial(-1), which would lead to an endless loop.
The same would happen in both cases if you just called factorial(-1) directly, which is why you should either check for > 0 instead (effectively treating every negative value as 0 and returning 1, or add another if condition and raise an error when N is negative.
EDIT: As pointed out in another answer, your implementation is not tail-recursive, meaning it accumulates memory for every recursive functioncall until it finishes or runs out of memory.
You can make the function tail-recursive, which allows Lua to treat it pretty much like a normal loop that could run as long as it takes to calculate its result:
local function factorial(n, acc)
acc = acc or 1
if n <= 0 then
return acc
else
return factorial(n-1, acc*n)
end
return Value
end
print(factorial(3))
Note though, that in the case of factorial, it would take you way longer to run out of stack memory than to overflow Luas number data type at around 21!, so making it tail-recursive is really just a matter of training yourself to write better code.
As the above answer and comments have pointed out, it is essential to have a base-case in a recursive function; otherwise, one ends up with an infinite loop.
Also, in the case of your factorial function, it is probably more efficient to use a helper function to perform the recursion, so as to take advantage of Lua's tail-call optimizations. Since Lua conveniently allows for local functions, you can define a helper within the scope of your factorial function.
Note that this example is not meant to handle the factorials of negative numbers.
-- Requires: n is an integer greater than or equal to 0.
-- Effects : returns the factorial of n.
function fact(n)
-- Local function that will actually perform the recursion.
local function fact_helper(n, i)
-- This is the base case.
if (i == 1) then
return n
end
-- Take advantage of tail calls.
return fact_helper(n * i, i - 1)
end
-- Check for edge cases, such as fact(0) and fact(1).
if ((n == 0) or (n == 1)) then
return 1
end
return fact_helper(n, n - 1)
end
What I believe to have here is a simple syntax error but unfortunately it has stumped my nooby mind. I have googled but had no results, I am looking to return true if the value is even and then false if the value is odd. Thanks!
x = 20
def MyEven(x):
if x / 2:
return True
else:
return False
return x
Generally there's no reason to return x unless the situation is more complex than this. If you only want to know if x is even, your code is fine except for two things: return x at the end, and the actual even check. x / 2 will simply return x divided by 2; for x = 20, this will return 10. What you want is x % 10; the % operator returns the remainder of division. If x is even, it returns 0; else, it returns 1.
However- if, for some reason, it is vital to your program that you return x at the end of the function, I would recommend packing your values into a tuple:
x = 20
def MyEven(x):
result = False # Will remain False if x isn't even
if x % 2 == 0:
result = True
return (x, result)
This will return a tuple whose first value is the passed x and the second is True or False depending on whether x is even.
this should do the trick
def is_even(num):
return num%2==0
this will return True if num is divisible by 2 (if it is even)
I've used this in other languages, but lua seems to be lacking this rather useful function.
Could one of you nice chappies provide me a lua function to get the sign of the number passed to it?
function math.sign(x)
if x<0 then
return -1
elseif x>0 then
return 1
else
return 0
end
end
Just in case anyone stumbles on this one:, here's my somehow shorter version:
function sign(x)
return x>0 and 1 or x<0 and -1 or 0
end
I think the idea is to return 1 or -1 to represent positive or negative. I don't think you would want it to return 0. Could have disastrous effects. Imagine trying to change the sign of a value by multiplying it by sign(x) when it returns 0. Instead of changing the sign you'd change the value to 0.
I'd stick with
function sign(x)
return (x<0 and -1) or 1
end
With LuaJIT, if the sign function gets JIT-compiled, this is actually faster:
function sign(x)
return math.max(math.min(x * 1e200 * 1e200, 1), -1)
end
The reason is that it avoids branches, which can be expensive. The double multiplication ensures that the result is correct even with inputs in the denormal range. Infinity can't be used because with an input of zero, it would produce NaN.
Tested in x86 only. I can't guarantee that it's the fastest in other processors supported by LuaJIT.
I built this one because I needed exact handling for -0 and +0 as well as for nan which all the other versions do not handle.
The idea is to interpret the sign bit directly and have a branchless version for this test. In pure Lua you'd have to go with tostring(x) checks +-0.
local _sign_helper = ffi.new("union { double d; uint64_t ul; int64_t l; }[1]")
local function sign(num)
-- to get access to the bit representation of double
_sign_helper[0].d = num
-- reinterpret it as ulong to access the sign bit
-- 1. move the bit down to the first bit
-- 2. multiply by -2 to move the range from 0/1 to 0/-2
-- 4. add 1 to reduce the range to -1/1
-- one test version for NaN handling (might be faster, did not test.)
-- return num ~= num and num or (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1)
-- branchless version: num - num will always be 0 except for nan.
return (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1) * ((num - num + 1) / 1)
end
print("(number < 0)", sign(-3)) -- > -1
print("(number > 0)", sign(3)) -- > 1
print("(nan)", sign(0 / 0)) -- > nan
print("(-inf)", sign(-0 / 1)) -- > -1
print("(+inf)", sign(0 / 1)) -- > 1
print("(+0)", sign(0)) -- > 1
print("(-0)", sign(-0)) -- > -1
You can also get the sign of a number like this:
x/ math.abs(x)
I'd only use that one for integers and since Lua doesn't distinguish ints from floats, I'd not use it in Lua at all.
A variation of that could be
function sign(x)
if x<0 then
return "-"
elseif x>0 then
return "+"
else
return ""
end
end
Mathematically, the sign is '+' or '-' (a symbol), not a number (as +1 or -1)
You can check for the sign like this:
i = -2
if i == math.abs(i) then -- or i >= 0
print "positive"
else
print "negative"
end