How can I evaluate a two-dimensional function in octave?
When I have a function which looks like this in WolframAlpha notation:
f(x, y) = {{x^2-y^2}, {x^2-y}}
(Matrix with one column and two rows)
I would like to evaluate it at any point like this: f(1, 0) which should give me the result {{1}, {1}}
E.g. using a function handle:
f = #(x,y) [x^2 - y^2; x^2 - y];
f(1,0)
Read the manual section on the syntax for creating matrices here
Related
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.
Write an octave function to implement f(x) = sin(3x)/(0.4+(x-2)^2).
Write an octave script to interpolate between the values of f(x) = sin(3x)/(0.4+(x-2)^2) sampled uniformly at up to 9 points in the interval x = [0,4].
I'm confused as to what this question is asking. I interpreted the 1st part as defining a function fx that can be called from anywhere to return the values of f(x) for a given x, but I'm not sure if the x's have to be inputs.
For the 2nd part, am I correct in using the interpl function?
My attempt:
Function file fx.m
function fx
x=(0:0.25:4);
y = sin(3*x)/(0.4+(x-2))^2
endfunction
But this only returns 1 value for y. I need to return 9 uniformly spaced samples. I feel as though I need to use a for loop somehow...
Script intpl.m
1;
yi=interpl(x,y,0.4:0.4:3.6)
I think your teacher wants something like:
function y = f(x)
y = ....x..... (fill your formula here but use elementwise operations [1])
endfunction
and then use this function for the given range:
x = linspace (0, 4, 9);
y = f(x)
if you want to have this in one file foo.m be sure to not start the file with the function definition. I normally use "1;" so your script foo.m becomes:
1;
function y = f(x)
x = ....;
endfunction
x = linspace (...);
y = f(x)
plot (x, y) # if you want to plot it
[1] https://www.gnu.org/software/octave/doc/interpreter/Arithmetic-Ops.html
I am a first time MATLAB user. I have a 2d array of t vs f in MATLAB. This 2d array correponds to a function, say f(t). I am using ode45 to solve a set of differential equations and f(t) is one of the coefficients i.e. I have a set of equations of the form x'(t)=f(t)x(t) or variations thereof. How do I proceed?
I need a way to convert my array of t vs f into a function that can be used in the ode45 method. Presumably, the conversion will do some linear interpolation and give me the equation of the best fit curve.
Or if there is another approach, I'm all ears!
Thank you!
This is a simple example with passing function as a parameter to right hand side of the ODE. Create files in the same directory and run main
main.m
t = 0:0.2:10; f = sin(t);
fun = #(xc) interp1(t, f, xc);
x0=0.5
% solve diff(x, t)=sin(t)
% pass function as parameter
[tsol, xsol] = ode45(#(t, x) diff_rhs(t, x, fun),[0.0 8.0], 0.5);
% we solve equation dx/dt = sin(x), x(0)=x0
% exact solution is x(t) = - cos(t) + x(0) + 1
plot(tsol, xsol, 'x');
hold on
plot(tsol, -cos(tsol) + x0 + 1, '-');
legend('numerical', 'exact');
diff_rhs.m
function dx = diff_rhs(t, x, fun)
dx = fun(t);
end
References in the documentation: interp1 and anonymous Functions.
I am trying to plot the function
f(x, y) = (x – 3).^2 – (y – 2).^2.
x is a vector from 2 to 4, and y is a vector from 1 to 3, both with increments of 0.2. However, I am getting the error:
"Subscript indices must either be real positive integers or logicals".
What do I do to fix this error?
I (think) I see what you are trying to achieve. You are writing your syntax like a mathematical function definition. Matlab is interpreting f as a 2-dimensional data type and trying to assign the value of the expression to data indexed at x,y. The values of x and y are not integers, so Matlab complains.
If you want to plot the output of the function (we'll call it z) as a function of x and y, you need to define the function quite differently . . .
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
z = f( repmat(x(:)',numel(y),1) , repmat(y(:),1,numel(x) ) );
surf(x,y,z);
xlabel('X'); ylabel('Y'); zlabel('Z');
This will give you an output like this . . .
The f = #(x,y) part of the first line states you want to define a function called f taking variables x and y. The rest of the line is the definition of that function.
If you want to plot z as a function of both x and y, then you need to supply all possible combinations in your range. This is what the line containing the repmat commands is for.
EDIT
There is a neat Matlab function meshgrid that can replace the repmat version of the script as suggested by #bas (welcome bas, please scroll to bas' answer and +1 it!) ...
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
[X,Y] = meshgrid(x,y);
surf(x,y,f(X,Y));
xlabel('x'); ylabel('y'); zlabel('z');
I typically use the MESHGRID function. Like so:
x = 2:0.2:4;
y = 1:0.2:3;
[X,Y] = meshgrid(x,y);
F = (X-3).^2-(Y-2).^2;
surf(x,y,F);
xlabel('x');ylabel('y');zlabel('f')
This is identical to the answer by #learnvst. it just does the repmat-ing for you.
Your problem is that the function you are using uses integers, and you are trying to assign a double to it. Integers cannot have decimal places. To fix this, you can make it to where it increases in increments of 1, instead of 0.2
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)