How does returning functions work in Lua? I'm trying to wrap my head around this derivative function but I'm having trouble understanding it.
function derivative(f, delta)
delta = delta or 1e-4
return function(x)
return (f(x + delta) - f(x))/delta
end
end
Any help is appreciated, thanks.
First see here.
Shortly, functions are first-class citizens and you an store them in variable and return from functions.
Second. In your example there is a closure to be created. It will have upvalues f and delta, wich can be used in inner function.
So when you call your derivative function, new closure will be created with copy of f and delta. And you can call it later like any other function
local d = derivative(f, 1e-6)
d(10)
EDIT: "Answer on but I'm having trouble understanding how the x argument is treated in the anonymous function in my example"
Each function have a signature, number of formal attributes, it will get.
In Lua you can call function with any number of arguments. Let's consider an example.
local a = function(x1, x2) print(x1, x2) end
a(1) // 1, nil
a(1, 2) // 1, 2
a(1, 2, 3) // 1, 2
When you call function in variable a, each given argument value, one by one will be matched with function argumentList. In 3-rd example 1 will be assigned to x1, 2 to x2, 3 will be thrown away. In term's of vararg function smth like this will be performed.
function a(...)
local x1 = (...)[1]
local x2 = (...)[2]
// Body
end
In your example x is treated as inner function argument, will be visible inside it, and initialized when you call your inner function instance.
f and delta will be unique for each function instance, as I mentioned above.
Hope my clumsy explanations will hit their goal and help you a little.
Related
This function is supposed to return a function handle to the nested function inside, but if the variable x is set to a negative value in the outer function, it doesn't work.
The inner nested function is just a constant function returning the value of the variable x that is set in the outer function.
function t=test(x)
x=-1;
function y=f()
y=x;
endfunction
t=#f;
endfunction
If I try to evaluate the returned function, e.g. test()(3), I get an error about x being undefined. The same happens if x is defined as a vector with at least one negative entry or if x is argument of the function and a negative default value is used for evaluation. But if I instead define it as some nonnegative value
function t=test(x)
x=1;
function y=f()
y=x;
endfunction
t=#f;
endfunction,
then the returned function works just fine. Also if I remove the internal definition of x and give the value for x as an argument to the outer function (negative or not), like
function t=test(x)
function y=f()
y=x;
endfunction
t=#f;
endfunction
and then evaluate e.g. test(-1)(3), the error doesn't occur either. Is this a bug or am misunderstanding how function handles or nested functions work?
The Octave documentation recommends using subfunctions instead of nested functions, but they cannot access the local variables of their parent function and I need the returned function to depend on the input of the function returning it. Any ideas how to go about this?
This is a bug that was tracked here:
https://savannah.gnu.org/bugs/?func=detailitem&item_id=60137
Looks like it was fixed and will be gone in the next release.
Also, to explain the different behavior of negative and positive numbers: I experimented a bit, and no variable that is assigned a computed value is being captured:
function t=tst()
x = [5,3;0,0]; # captured
y = [5,3;0,0+1]; # not captured
z = x + 1; # not captured
function y=f()
endfunction
t=#f;
endfunction
>> functions(tst)
ans =
scalar structure containing the fields:
function = f
type = nested
file =
workspace =
{
[1,1] =
scalar structure containing the fields:
t = #f
x =
5 3
0 0
}
The different behavior of negative and positive numbers are probably caused by the minus sign - before the numbers being treated as a unary operator (uminus).
As of octave version 5.2.0 the nested function handles were not supported at all. I'm going to guess that is the novelty of the version 6.
In octave functions are not variables, the engine compiles\translates them at the moment of reading the file. My guess would be that behavior you are observing is influenced by your current workspace at the time of function loading.
The common way for doing what you are trying to do was to generate the anonymous (lambda) functions:
function t = test1(x=-1)
t = #()x;
end
function t = test2(x=-1)
function s = calc(y,z)
s = y + 2*z;
end
t = #(a=1)calc(a,x);
end
Note that default parameters for the generated function should be stated in lambda definition. Otherwise if you'd call it like test2()() it would not know what to put into a when calling calc(a,x).
If you are trying to create a closure (a function with associated state), octave has limited options for that. In such a case you could have a look at octave's object oriented functionality. Classdef might be useful for quick solutions.
I want to plot a function using surface in Julia. I manage to plot te desired function:
x = 0:0.1:4
y = 0:0.1:4
f(x,y) = x^0.2 * y^0.8
surface(x, y, f, camera=(10,30),linealpha=0.3, fc=:heat)
However, I would f(*) to be a proper function over which I could also optimize (e.g. utility maximisation in economics). This is my attempt:
function Utility(x1, x2)
u= x.^0.2 .* y.^0.8
return u
end
But it unfortunately does not work. Can anybody help me?
Best
Daniel
I think Benoit's comment really should be the answer, but let me expand a little bit.
First of all, an inline function definition is not any different from a multi-line function definiton (see the first two examples in the docs here). Therefore, doing
utility(x, y) = x^0.2 * y^0.8
will give you a function that works exactly like
function utility(x, y)
x^0.2 * y^0.8
end
However, your Utility function is actually different from your f function - you are defining it with the arguments x1 and x2, but in the function body you are using y rather than x2.
This would ordinarily raise an undefined variable error, except that in the code snippet you posted, y is already defined in global scope as the range 0:0.1:4, so the function will use this:
julia> y = 0:0.1:4
0.0:0.1:4.0
julia> u(x1, x2) = x1 .^ 0.2 * y .^ 0.8
u (generic function with 1 method)
julia> u(2.0, 0.0)
41-element Array{Float64,1}:
0.0
0.18205642030260805
0.3169786384922227
...
this is also where your introduction of broadcasting in the Utility function (the second difference between your two examples as Benoit pointed out) comes back to haunt you: calling the function while relying on it to use the global variable y would error immediately without broadcasting (as you can't exponentiate a range):
julia> u2(x1, x2) = x1^0.2 * y^0.8
u2 (generic function with 1 method)
julia> u2(2.0, 0.0)
ERROR: MethodError: no method matching ^(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Float64)
with broadcasting, however, this exponentiation works and returns the full range, with every element of the range exponentiated. Thus, your function returns an array rather than a single number (as you can see above from my call to u(2.0, 0.0). This is what Plots complains about - it doesn't know how to plot an array, when it expects to just be plotting a single data point.
I have an array of functions and I want to make another function using a weighted sum over these functions. Let's say T=[T1, ..., T20]
and T1(x,y)=x^2+5, T2(x,y)=sin(x+y), ...
I want to make another function named g(x,y)=10*T1(x,y)+...+32*T20(x,y). the coefficients may change so I want to use some sort of loop but I couldn't.
This is my try, probably there is a better solution.
If you can change the signature of g:
g(x, y, weights, T) = sum(weights[i]*Ti(x,y) for (i,Ti) in enumerate(T))
If you need exactly this signature g(x,y), I suggest a generator function:
generate_g(weights, T) = (x,y) -> sum(weights[i]*Ti(x,y) for (i,Ti) in enumerate(T))
You pass the weights into it, and it returns a new function, that takes x and y as arguments. Here is an example
julia> T1(x,y)=x^2+5; T2(x,y)=sin(x+y); T=[T1, T2];
julia>g = generate_g([10,11], T)
#3 (generic function with 1 method)
julia> g(1,2)
61.55232008865854
When the weights change, you can generate a new g.
I have created a function that returns the magnitude of a vector.the output is 360x3 dimension matrix. the input is 360x2.
Everything works fine outside the function. how do i get it to work ?
clc
P_dot_ij_om_13= rand(360,2); // 360x2 values of omega in vectors i and j
//P_dot_ij_om_13(:,3)=0;
function [A]=mag_x(A)
//b="P_dot_ijOmag_"+ string(k);
//execstr(b+'=[]'); // declare indexed matrix P_dot_ijOmag_k
//disp(b)
for i=1:1:360
//funcprot(0);
A(i,3)=(A(i,2)^2+A(i,1)^2)^0.5; //calculates magnitude of i and j and adds 3rd column
disp(A(i,3),"vector magnitude")
end
funcprot(1);
return [A] // should return P_dot_ijOmag_k in the variable browser [360x3 dim]
endfunction
mag_x(P_dot_ij_om_13);
//i=1;
//P_dot_ij_om_13(i,3)= (P_dot_ij_om_13(i,2)^2+P_dot_ij_om_13(i,1)^2)^0.5;// example
You never assigned mag_x(P_dot_ij_om_13) to any variable, so the output of this function disappears into nowhere. The variable A is local to this function, it does not exist outside of it.
To have the result of calculation available, assign it to some variable:
res = mag_x(P_dot_ij_om_13)
or A = mag_x(P_dot_ij_om_13) if you want to use the same name outside of the function as was used inside of it.
By the way, the Scilab documentation discourages the use of return, as it leads to confusion. The Scilab / Matlab function syntax is different from the languages in which return specifies the output of a function:
function y = sq(x)
y = x^2
endfunction
disp(sq(3)) // displays 9
No need for return here.
I'm trying to generate .bmp graphics in MATLAB and I'm having trouble summing functions together. I'm designing my function such that given an arbitrary set of inputs, my function will add an arbitrary number of functions together and output a function handle. The inputs are coefficients to my general function so I can specify any number of functions (that only differ due to their coefficients) and then add them together into a function handle. What I've tried to do is create each function as a string and then concatenate them and then write them as a function handle. The main problem is that because x and y aren't defined (because I'm trying to create a function handle) MATLAB can't add them regularly. My current attempt:
function HGHG = anyHGadd(multi) %my array of inputs
m=length(multi);
for k=3:3:m;
m1=multi(k-2); %these three are the coefficients that I'd like to specify
n1=multi(k-1);
w1=multi(k);
HGarrm1=hermite(m1); %these generate arrays
HGarrn1=hermite(n1);
arrm1=[length(HGarrm1)-1:-1:0];%these generate arrays with the same length
arrn1=[length(HGarrn1)-1:-1:0];%the function below is the general form of my equation
t{k/3}=num2str(((sum(((sqrt(2)*x/w1).^arrm1).*HGarrm1))*(sum(((sqrt(2)*y/w1).^arrn1).*HGarrn1))*exp(-(x^2+y^2)/(w1^2))));
end
a=cell2mat(t(1:length(t)));
str2func(x,y)(a);
Any help would be much appreciated. I haven't seen much on here about this, and I'm not even sure this is entirely possible. If my question isn't clear, please say so and I'll try again.
Edit: The fourth from last line shouldn't produce a number because x and y aren't defined. They can't be because I need them to be preserved as a part of my function handle. As for a stripped down version of my code, hopefully this gets the point across:
function HGHG = anyHGadd(multi) %my array of inputs
m=length(multi);
for k=3:3:m;
m1=multi(k-2); %these three are the coefficients that I'd like to specify
n1=multi(k-1);
w1=multi(k);
t{k/3}=num2str(genericfunction(x,y,n1,m1,n1,w1); %where x and y are unspecified
end
a=cell2mat(t(1:length(t)));
str2func(x,y)(a);
Edit I am expecting this to output a single function handle that is the sum of an arbitrary number of my functions. However, I'm not sure if using strings would be the best method or not.
Your question is not very clear to me, but I think you are trying to create a function that generate output functions parametrized by some input.
One way is to use closures (nested function that access its parent function workspace). Let me illustrate with an example:
function fh = combineFunctions(funcHandles)
%# return a function handle
fh = #myGeneralFunction;
%# nested function. Implements the formula:
%# f(x) = cos( f1(x) + f2(x) + ... + fN(x) )
%# where f1,..,fN are the passed function handles
function y = myGeneralFunction(x)
%# evaluate all functions on the input x
y = cellfun(#(fcn) fcn(x), funcHandles);
%# apply cos(.) to the sum of all the previous results
%# (you can make this any formula you want)
y = cos( sum(y) );
end
end
Now say we wanted to create the function #(x) cos(sin(x)+sin(2x)+sin(5x)), we would call the above generator function, and give it three function handles as follows:
f = combineFunctions({#(x) sin(x), #(x) sin(2*x), #(x) sin(5*x)});
Now we can evaluate this created function given any input:
>> f(2*pi/5) %# evaluate f(x) at x=2*pi/5
ans =
0.031949
Note: The function returned will work on scalars and return a scalar value. If you want it vectorized (so that you can apply it on whole vector at once f(1:100)), you'll have to set UniformOutput to false in cellfun, then combine the vectors into a matrix, sum them along the correct dimension, and apply your formula to get a vector result.
If your goal is to create a function handle that sums the output of an arbitrary number functions, you can do the following:
n = 3; %# number of function handles
parameters = [1 2 4];
store = cell(2,3);
for i=1:n
store{1,i} = sprintf('sin(t/%i)',parameters(i));
store{2,i} = '+'; %# operator
end
%# combine such that we get
%# sin(t)+sin(t/2)+sin(t/4)
funStr = ['#(t)',store{1:end-1}]; %# ignore last operator
functionHandle = str2func(funStr)
functionHandle =
#(t)sin(t/1)+sin(t/2)+sin(t/4)