I’m tryin to build a function that take 2 inputs limits
and Function
, so I wrote the below:
function Σ(limits, f::Function)
@show limits
@show f
end
Σ((i=1:3), :(x->x^2))
But it could not run, with the below error:
ERROR: LoadError: function Σ does not accept keyword arguments
I did not understand shall I change something in the function declaration, or in the function execution?
Σ((i=1:3,), x->x^2)
? It depends what you’re trying to do. :(x->x^2)
is a quoted expression, not a function.
The typeof
function is your friend here.
julia> typeof(:(x->x^2))
Expr
julia> :(x->x^2) isa Function
false
julia> typeof((i=1:3))
ERROR: function typeof does not accept keyword arguments
Stacktrace:
[1] kwfunc(::Any) at ./boot.jl:321
[2] top-level scope at none:0
julia> typeof((i=1:3,))
NamedTuple{(:i,),Tuple{UnitRange{Int64}}}
As such, to call your function you need to write it as
Σ((i=1:3,), x->x^2)
1 Like
Thanks, but how can I read the limits range in my function!
I want to get something like:
start = limit.first
stop = limits.last
Then you can pass a Pair
:
julia> limits = 1 => 3
1 => 3
julia> limits.first
1
julia> limits.second
3
Then you didn’t use a pair. Can you show your code instead of making people guessing what you have?
Here it is:
function Σ(limits, f::Function)
@show limits
out = 0.0
start = limits.first
stop = limits.second
for i=start:stop
out += f(i)
end
out
end
result = Σ((i=1:6,), n->(6n + 2))
@show result
You are passing a named tuple and not a Pair as I suggested. Change (i = 1:6,)
to 1 => 6
:
julia> function Σ(limits, f::Function)
out = 0.0
start = limits.first
stop = limits.second
for i = start:stop
out += f(i)
end
out
end
Σ (generic function with 1 method)
julia> Σ(1=>6, n->(6n + 2))
138.0
But if you just use start
and stop
to recreate the range start:stop
in the function, then maybe it makes more sense to just use the range, that is, pass 1:6
and remove start
and stop
:
julia> function Σ(range, f::Function)
out = 0.0
for i = range
out += f(i)
end
out
end
Σ (generic function with 1 method)
julia> Σ(1:6, n->(6n + 2))
138.0
2 Likes
Thanks a lot, I loved the solution of using range
I re-wrote it as:
function Σ(range, f::Function)
out = 0.0
(for i = range; out += f(i) ; end)
out
end
result = Σ(1:6, n->(6n + 2))
@show result
If you don’t mind relying on the already existing sum
function, this is also an option:
Σ(range, f::Function) = sum(f(i) for i in range)
2 Likes
Supreme, very silky solution, thanks
So, Apparently I can avoid adding my function, by using the below
f(n) = 6n + 2
result = sum(f(n) for n=1:6)
@show result
Here’s the slickest way (you can pass the function you are summing with as the first argument):
julia> f(n) = 6n + 2
f (generic function with 1 method)
julia> sum(f, 1:6)
138
3 Likes
By the way, with my Reduce.jl package, you can do this
julia> using Reduce
Reduce (Free CSL version, revision 4590), 11-May-18 ...
julia> @force using Reduce.Algebra
julia> ∑(:(x^2),:x,1,3)
14
julia> ∏(:(x^2),:x,1,3)
36
it takes summation limits and symbolic expressions as arguments, of course it’s not as fast as using a function.
Thanks, the link is not working.
They work for me. I’m not sure I fully understand the documentation though.