Convert function in Matlab into appropriate form - matlab

I have written a function feval that takes two arguments and spits out a number.
Now I wanted to use the command integral2 in order to integrate over my function feval(x,y).
The problem seems to be that integral2 thinks that I have a function that can take two arrays as arguments and apply pairwise operations on them. Unfortunately, this is not the case. My function can only works with 2 numbers and not with full arrays. Is there any standard method to make this work?
Actually, this is my code now and MATLAB claims that
q = integral2( #(x,y) arrayfun(func_cross_scat,x,y),0,2*pi,0,pi);
my function(feval, that i renamed func_cross_scat does not get enough input arguments)

Feed integral2 not with feval, but with feval_wrapper defined as
feval_wrapper = #(x,y) arrayfun(feval, x, y)
x and y can now be arrays (of the same size). This works because arrayfun calls feval for each pair of elements of the input arrays x, y and gives an array as the result.
As a side comment, "feval" is probably not a good name for your function, because Matlab has a built-in feval.

Related

How do I pass a polynomial variable into a matlab function?

I am just getting started with MATLAB and I have written a function to produce the binomial expansion of (x-a)^n when given x, a and n. As far as I can tell my code should work, but I do not seem to be using the function variables correctly.
function expand(a,n,x)
f = 0;
for k = 0:1:n
f = f + nchoosek(n,k).*x.^(n-k).*(-a).^k;
end
end
I need to be able to call the function and have it output f as the expanded polynomial in x, for example calling expand(1,3,x) should return x^3-3*x^2+3*x-1, but instead, calling it gives this error:
Unrecognized function or variable 'x'. It seems like it wants me to call the function with x being another number but I in fact need it to be able to be any letter to be used as the variable in the polynomial.
I know in Maple I would specify the variable type in the function to be x::name so I'm assuming there's something similar in MATLAB that I don't yet know.
Thanks for any help.
There are two ways to go about this:
Create x as a symbolic variable. For example, syms x; expand(a,n,x). This gives you the power of using the symbolic toolbox features like simplify(), but comes with a bit of a performance penalty. You should avoid using the symbolic toolbox in intensive calculations.
Return an anonymous function, f=#(X)sum(arrayfun(#(k)nchoosek....,1:n). This has better performance and does not require double(subs(...)) when you want an actual numeric value, but may be too difficult to implement for a beginner.

Nested call to integral fails

Try this piece of code, which works fine.
a=1;b=2;
% A two-variate function
f2= #(x,y) x+y;
derivedF2=#(x) integral(#(y) f2(x,y), a,b);
% Test the evaluation of the derived function handle
derivedF2(0);
% Test the integration of the derived function handle
% integralVal=integral(derivedF2,a,b);
% integralVal=integral(#(x) derivedF2(x),a,b);
% Test plotting of the derived function handle
figure(11);
ezplot(derivedF2);
But if you uncomment the lines starting with integralVal. The code breaks.
Apparently, the derived function handle does not support integration operation, or have I missed something?
Short answer: you should add the 'ArrayValued' option:
integralVal=integral(derivedF2,a,b, 'ArrayValued', true);
Explanation
You should read your error message:
Output of the function must be the same size as the input. If FUN is an array-valued integrand, set the 'ArrayValued'
option to true.
Because derivedF2 is evaluated in a vectorised way, i.e. it evaluates f at different y coordinates at once by supplying a y vector instead of a single scalar, MATLAB is unable to evaluate the outer integral in a vectorised way too. Therefore you should add the 'ArrayValued' option to the outer integral, i.e.:
integralVal=integral(derivedF2,a,b, 'ArrayValued', true);
Note that ezplot also generate the following related warning:
Warning: Function failed to evaluate on array inputs; vectorizing the function may speed up its evaluation and avoid the
need to loop over array elements.
Note that the problem is purely related to nested calls to integral, also the following code will result in the same error:
integralVal=integral(#(x) integral(#(y) f2(x,y), a,b),a,b);
What is an Array Valued function?
... a function that accepts a scalar input and returns a vector, matrix, or N-D array output.
So, #(y) f2(x, y) is an array valued function if x is an array, i.e. it returns an array for a scalar input of y.
Two possibilities exist to avoid array valued problem:
Avoid that #(y) f2(x, y) is an array valued function, i.e. avoid that x is an array. This can be done by indicating that derivedF2 is an array valued function as elaborated above, although - strictly speaking - it is not an array valued function, i.e. the integral should have the same number of outputs and inputs. However, it uses internally an array valued function, i.e. #(x) f2(x, y) is an array valued function as Matlab evaluates by default the integrand in a vectorised way, i.e. it uses a vector for y.
Tell Matlab that #(y) f2(x, y) is an array valued function:
derivedF2=#(x) integral(#(y) f2(x,y), a,b, 'ArrayValued', true);
This may be a more intuitive approach, but is slower as the internal integral is called much often than the external integral.
An alternative interpretation of Array Valued is that you tell matlab to not use vectorisation, but for this interpretation the name Array Valued is somewhat misleading.

Simulink: Syntax error

I have a syntax error in the following equation:
((Cs+Cf)*u(1)/Cf-Cs*u(2)/Cf)*(1/(1+(Cs+Cf)/(Cf*(10^(u0/20)))))*(1-exp(-(pi*f1*(10^9)/(fs*10^6))*(Cf/(Cs+Cf)+1/(10^(u0/20)))))
Uppercase/lowercase checked, they are ok. What could be the problem?
As mentioned in the documentation of Interpreted MATLAB Function,
The Interpreted MATLAB Function block accepts one real or complex
input of type double ...
Here you're using multiple inputs which are Cs, Cf, u0, u, f1 and fs.
How to solve it?
Solution-1: Using Interpreted MATLAB Function block
One way to deal with this problem would be to concatenate all the input matrices into a single matrix and use its indices to represent each value in the equation.
e.g; if you have:
u=[1 5]; u0=5; Cs=1; Cf=1; f1=1; fs=20;
Concatenate them into a single matrix in your workspace. Something like the following would do:
new=[u, u0, Cs, Cf, f1, fs];
%It could be different depending on the dimensions of these
%variables that you actually have
then use the following equation according to the indices of new in the Interpreted MATLAB Function block:
((new(4)+new(5))*u(1)/new(5)-new(4)*u(2)/new(5))*(1/(1+(new(4)+new(5))/(new(5)*(10^(new(3)/20)))))*(1-exp(-(pi*new(6)*(10^9)/(new(7)*10^6))*(new(5)/(new(4)+new(5))+1/(10^(new(3)/20)))))
Solution-2: Using MATLAB Function block
You can also use the MATLAB Function block in which you can use multiple inputs. For your case, write the following code in it:
function y = foo(u,u0,Cs,Cf,f1,fs)
y = ((Cs+Cf)*u(1)/Cf-Cs*u(2)/Cf)*(1/(1+(Cs+Cf)/(Cf*(10^(u0/20)))))* ...
(1-exp(-(pi*f1*(10^9)/(fs*10^6))*(Cf/(Cs+Cf)+1/(10^(u0/20)))));
and connect Constant blocks with its inputs and give the values of the constants equal to the respective variables that you want to use.

fminsearch multiple parameters matlab

I'm trying to use fminsearch with multiple parameters but I can't seem to even get it working with two. I've also tried using optimization tool in matlab but then I get:
Optimization running.
Error running optimization.
Not enough input arguments.
What i do:
fval = fminsearch(#g,[1 1])
The function g looks like this:
function r=g(x,y)
r=x.^3+3*x*y.^2+12*x*y;
end
but i get this:
Error using g (line 2)
Not enough input arguments.
Error in fminsearch (line 190)
fv(:,1) = funfcn(x,varargin{:});
Your function g takes two inputs, x and y, however you supply fminsearch one input, the vector [1 1]. You need to rewrite it so that fminsearch only needs a single vector as input, but then that vector is split into two numbers to input into g.
fminsearch(#(v) g(v(1),v(2)),[1 1])
This makes an anonymous function that takes a vector as input (v) and then uses the first element (v(1)) as the first input to g, and the second element as the second input.

multiply two functions with each other (matlab)

I'm trying to multiply two functions with each other and plot the result. but I got an empty figure!
the both functions work fine if I plot each one like this:
plot(x,ramp3(x))
hold on
plot(x,unitStep(3-x))
this is my code:
clear all
clc
x=0:0.001:20;
y3=#(x) ramp3(x).*unitStep(3-x);
plot(x,y3)
axis([-4 4 -2 2])
When you use the #(...) ... syntax, MATLAB generates an anonymous function, treating the argument list within the parentheses as inputs. The scope of those variables is limited to the anonymous function. The function is not evaluated until you call it and pass in valid inputs.
In your case y3 is a function handle. You need to use something like plot(x,y3(x)) to actually evaluate the function y3 at the points in your array x.