how to evaluate to multivariable function - matlab

Consider the function f(y1,y2,y3,y4,z1)=(-(z1^3)/(y3^2))(3(y2-y1+y3^(-1)-z1/10)^2+(1/5)(y2-y1+y3^(-1)-(z1)/10))-y4 with 5 variables. When I put f(1,1,1,1,1) I find the answer but when I write f(v) in which v=(1,1,1,1,1) matlab does not work. How can I do that (by the second way)?

You could write a wrapper function, that will take a vector as input argument and 'unpacks' this vector before calling your function.
f(y1,y2,y3,y4,z1) = (-(z1^3)/ ...; % your function
fv(v) = f(v(1),v(2),v(3),v(4),v(5));
Or alternatively, make f refer to elements in the input vector by using the appropriate indices:
f(v) = (-(v(5)^3)/(v(3)^2)); ... % etc.

Related

Calculating the numeric derivative

So i'm a little confounded by how to structure my problem.
So the assignment states as following:
Type a m-file numerical_derivative.m that performs numerical derivation. Use
it to calculate f'(-3) when f(x) = 3x^2 /(ln(1-x))
In the m-file you to use h = 10^-6 and have the following mainfunction:
function y = numericalderivative (f, x)
% Calculates the numerical value in the case of f in punk x.
% --- Input ---
% f: function handle f(x)
% x: the point where the derivative is calculated
% --- output ---
% y: the numerical derivative of f on the point x
If I want to save it as a file and run the program in matlab, does't it make it redundant to use handles then?
I won't give you the answer to your homework, but perhaps a simpler example would help.
Consider the following problem
Write a function named fdiff which takes the following two arguments:
A function f represented by a function handle which takes one argument,
and a point x which can be assumed to be in the domain of the f.
Write fdiff so that it returns the value f(x) - f(x-1)
Solution (would be in the file named fdiff.m)
function result = fdiff(f, x)
result = f(x) - f(x-1);
end
Example Use Cases
>> my_function1 = #(x) 3*x^2 /(log(1-x));
>> fdiff(my_function1, -3)
ans =
-10.3477
>> my_function2 = #(x) x^2;
>> fdiff(my_function2, 5)
ans =
9
What you've created with fdiff is a function which takes another function as an input. As you can see it doesn't just work for 3*x^2 /(log(1-x)) but any function you want to define.
The purpose of your assignment is to create something very similar, except instead of computing f(x) - f(x-1), you are asked write a function which approximates f'(x). Your use-case will be nearly identical to the first example except instead of fdiff your function will be named numericalderivative.
Note
In case it's not clear, the second example defines the my_function2 as x^2. The value returned by fdiff(my_function2, 5) is therefore 5^2 - 4^2 = 9.
When you make this as a function file and run this in MATLAB without any input arguments i.e., 'f' and 'x', it will give you the error: 'not enough input arguments'. In order to run the file you have to type something like numericalderivative (3x^2 /(ln(1-x)), 5), which gives the value of the numerical derivative at x = 5.
Functions and, in MATLAB function files are a simple implementation of the DRY programming method. You're being asked to create a function that takes a handle and an x file, then return the derivative of that function handle and that x value. The point of the function file is to be able to re-use your function with either multiple function handles or multiple x values. This is useful as it simply involves passing a function handle and a numeric value to a function.
In your case your script file or command window code would look something like:
func = #(x) (3*x^2)/log(1-x);
x = -3;
num_deriv = numericalderivative(func,x);
You should write the code to make the function numericalderivative work.

ODE solver producing runtime error - not enough input arguments [duplicate]

I have a use case as follows:
Inside F.m I have a function F that takes as its argument a 2 x 1 matrix x. F needs to matrix multiply the matrix kmat by x. kmat is a variable that is generated by a script.
So, what I did was set kmat to be global in the script:
global kmat;
kmat = rand(2);
In F.m:
function result = F(x)
global kmat;
result = kmat*x;
end
Then finally, in the script I have (x_0 has already been defined as an appropriate 2 x 1 matrix, and tstart and tend are positive integers):
xs = ode45(F, [tstart, tend], x_0);
However, this is causing the error:
Error using F (line 3)
Not enough input arguments.
Error in script (line 12)
xs = ode45(F, [tstart, tend], x_0);
What is going on here, and what can I do to fix it? Alternatively, what is the right way to pass kmat to F?
Firstly, the proper way to handle kmat is to make it an input argument to F.m
function result = F(x,kmat)
result = kmat*x;
end
Secondly, the input function to ode45 must be a function with inputs t and x (possibly vectors, t is the dependent variable and x is the dependent). Since your F function doesn't have t as an input argument, and you have an extra parameter kmat, you have to make a small anonymous function when you call ode45
ode45(#(t,x) F(x,kmat),[tstart tend],x_0)
If your derivative function was function result=derivative(t,x), then you simply do ode45(#derivative,[tstart tend],x_0) as Erik said.
I believe F in ode45(F,...) should be a function handle, i.e. #F. Also, you can have a look at this page of the MATLAB documentation for different methods to pass extra parameters to functions.

Matlab - how to build functions

Matlab has the function Legendre that returns to an integer m and real number r a vector of length m+1.
Now I want to define another function fun that gives me only the first component of this vector per fixed m, so I want to define a function fun(m,r) that gives me the first component of the vector legendre(m,x). The point is that fun(m,r) should also be a function, just like legendre. Does anybody know how to do this?
Define the function as follows:
function out = fun(n,x)
temp = legendre(n,x); %// store output of "legendre" in a temporary variable
out = temp(1); %// return only desired element
Of course, this should be placed in a file fun.m within Matlab's path.
Alternatively, if you are feeling hackish, you can use
getfield(legendre(n,x), {1})
to extract the first element of legendre(n,x) directly (without a temporary variable). This allows defining fun as an anonymous function as follows:
fun = #(n,x) getfield(legendre(n,x), {1});

defining different cases for function im matlab (symfun)

i want to create a function (symfun), and i want to divide it to cases, i.e if t> then then answer will be a and if t<0 the answer will be b.
the thing is, that matlab wont allow me to put an if statements after a sym function.
>> l = symfun(0, [m]);
>> l(m) = if m>0 3
also i tried to create a function:
function [x1] = xt_otot_q3(t)
and tried to connect between the two functions:
>> l(m) = xt_otot_q3(m)
Conversion to logical from sym is not possible.
is there any way to break a symfun into cases?
Not sure that I understand what you want.
This code 'combines' the functions symfun and xt+otot_q3 defined below:
function test;
m=randn(4); % N(0,1) random numbers
l=xtotot_q3(symfun(0,m)) % combine xt_otot_q3 and symfun
l=symfun(0,xtotot_q3(m)) % combine symfun and xt_otot_q3
return
function lval=symfun(thr,rval);
lval=ones(size(rval)); % output, size of input, = 1
lval(rval<thr)=-1; % output = -1 if input < thr
return
function lval=xtotot_q3(rval);
lval=3*rval+1; % some function, in this case 3 * input + 1
return
You can save the whole bit as test.m and then call test from the matlab prompt. Maybe if you start with this then you can modify it to fit your needs.

Merging function handles in MATLAB

I'm currently coding a simulation in MATLAB and need some help in regards to an issue that I've been having.
I'm working on a problem where I have n separate anonymous function handles fi stored in cell array, each of which accepts a 1×1 numeric array xi and returns a 1×1 numeric array yi.
I'm trying to combine each of these anonymous function handles into a single anonymous function handle that accepts a single n×1 numeric array X and returns a single n×1 numeric array Y, where the i-th elements of X and Y are xi and yi = fi (xi), respectively.
As an example, let n = 2 and f_1, f_2 be two function handles that input and output 1×1 arrays and are stored in a cell array named functions:
f_1 = #(x_1) x_1^2
f_2 = #(x_2) x_2^3
functions = {f_1, f_2}
In this example, I basically need to be able to use f_1 and f_2 to construct a function handle F that inputs and outputs a 2×1 numeric array, like so:
F = #(x) [f_1(x(1,1)); f_2(x(2,1))]
The question is how to generalize this for an arbitrary number n of such functions.
It is difficult to define such a function using the inline #()-anonymous
syntax (because of the requirement for the function’s body to be
an expression).
However, it is possible to define a regular function that runs over
the items of a given vector and applies the functions from a given
cell array to those items:
function y = apply_funcs(f, x)
assert(length(f) == length(x));
y = x;
for i = 1 : length(f)
y(i) = feval(f{i}, x(i));
end
end
If it is necessary to pass this function as an argument to another
one, just reference it by taking its #-handle:
F = #apply_funcs
This can be solved using a solution I provided to a similar previous question, although there will be some differences regarding how you format the input arguments. You can achieve what you want using the functions CELLFUN and FEVAL to evaluate your anonymous functions in one line, and the function NUM2CELL to convert your input vector to a cell array to be used by CELLFUN:
f_1 = #(x_1) x_1^2; %# First anonymous function
f_2 = #(x_2) x_2^3; %# Second anonymous function
fcnArray = {f_1; f_2}; %# Cell array of function handles
F = #(x) cellfun(#feval,fcnArray(:),num2cell(x(:)));
Note that I used the name fcnArray for the cell array of function handles, since the name functions is already used for the built-in function FUNCTIONS. The colon operator (:) is used to turn fcnArray and the input argument x into column vectors if they aren't already. This ensures that the output is a column vector.
And here are a few test cases:
>> F([2;2])
ans =
4
8
>> F([1;3])
ans =
1
27
#you can try
f=#(x)[x(1)^2;x(2)^3]
>>f([1,2])
ans =
1
8
>>f([2,3])
ans =
4
27