MATLAB: Using an anonymous function within symsum, then fsolve - matlab

In MATLAB, I wish to define an anonymous function which has a definite sum in it, and another anonymous function in that. Here's a MWE which hopefully describes what I am trying to do:
clear; n=1; syms j; a=0; b=sqrt(0.5);
Finv = #(x) logninv(x,a,b);
fun = #(x) 0.5-symsum(Finv(j*x), j, 1, n+1);
fsolve(fun,0.1)
The error returned is:
Error using symfun>validateArgNames (line 211) Second input must be a
scalar or vector of unique symbolic variables.
Error in symfun (line 45)
y.vars = validateArgNames(inputs);
Error in sym/subsasgn (line 762)
C = symfun(B,[inds{:}]);
Error in logninv (line 60) p(p < 0 | 1 < p) = NaN;
Error in #(x)logninv(x,a,b)
Error in #(x)0.5-symsum(Finv(j*x),j,1,n+1)
Error in fsolve (line 217)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot
continue.
For this particular choice of Finv I solved it using eval and feval as follows:
clear; n=1; syms j; a=0; b=sqrt(0.5);
Finv = #(x) logninv(x,a,b);
fun = #(x) 0.5-eval(symsum(feval(symengine,'logninv',j*x,a,b), j, 1, n+1));
fsolve(fun,0.1)
which produces the answer in this special case because Finv=#(x) logninv(x,a,b), but this defeats the point, which is that I want to be able to define Finv as a univariate function of my choice, not necessarily a predefined MuPAD expression like 'logninv'.
Any advice would be most appreciated.

Try to force the second variable (i.e., j) as being a symbolic variable with a scalar (numerical) data type. Note in his code, that is only variable is not being initialized.
clear; n=1; syms j integer; a=0; b=sqrt(0.5);
Alternatively, you can check assumptions on each variable. For example,
assumptions(j)

Related

Numerical Convolution of Two Signals in MATLAB and Plotting the Output

without using conv() command, I want to convolve two signals:
This is the code I write:
syms n k i
f= #(n) 2.*(0<=n<=9);
h(n)=((8/9)^n).*heaviside(n-3);
L = length(f);
M = length(h(n));
out=L+M-1;
y=zeros(1,out);
for i = 1:L
for k = 1:M
y(i+k-1) = y(i+k-1) + h(k)*f;
end
end
However, I get an error:
Unable to perform assignment because value of type 'sym' is not convertible to 'double'.
Error in untitled7 (line 13)
y(i+k-1) = y(i+k-1) + h(k)*f;
Caused by:
Error using symengine
Unable to prove '(0.0 <= 0.0) <= 0.0' literally. Use 'isAlways' to test the statement mathematically.
I cannot find a way to fix it and also I do not know how to plot it at the end because of this. Can you help me in both of these issues please?
example how to convolve without command conv
nstop=20;
n1=[-nstop:1:nstop];
n0=nstop+1 % n1(n0)=0
h=zeros(1,numel(n1));
x1=zeros(1,numel(n1));
h(n0+[3:nstop])=(8/9).^[3:nstop];
x1(n0+[0:9])=2;
X1=flip(hankel(x1),2)
H=repmat(h,numel(n1),1);
conv_x_h=sum(X1.*H,2)';
n2=[0:numel(n1)-1]; % time reference for resulting conv
figure;
stem(n1,x1)
hold on
stem(n1,h);
grid on
legend('x1(n)','h(n)')
figure
stem(n2,conv_x_h)
grid on
title('conv(x1,h)')

Integral and scalar product function handles matlab

I need to compute this kind of integral
I defined the two f(x,y) and g(x,y) inside a single function
h = {#(x,y) f, #(x,y) g};
where f and g are formulas defined before. In this way I have a 1x2 cell and I want to compute the scalar product as
F = #(x,y) dot(h,E)
where E is a vector 2x1 and then integrate
int = integral2(F,a,b,c,d);
giving me this error
Undefined function 'conj' for input arguments of type 'cell'.
Error in dot (line 37)
c = sum(conj(a).*b);
Error in tm_np>#(R,PHI)dot(e_n_even,E)
Error in integral2Calc>integral2t/tensor (line 228)
Z = FUN(X,Y); NFE = NFE + 1;
Error in integral2Calc>integral2t (line 55)
[Qsub,esub] = tensor(thetaL,thetaR,phiB,phiT);
Error in integral2Calc (line 9)
[q,errbnd] = integral2t(fun,xmin,xmax,ymin,ymax,optionstruct);
Error in integral2 (line 106)
Q = integral2Calc(fun,xmin,xmax,yminfun,ymaxfun,opstruct);
I don't understand why is giving me this error. As result of the integral I should have a 2x1 vector
The problem is the generation of your data. integral2 accepts only functions that get #(x,y) as vector input and return the same size. in your case h is already not that, and F has no #(x,y) inputs (well, it has, but you decided not to pass them to h!!!).
% sample data
f=#(x,y)x.^2+y;
g=#(x,y)y.^2+x+3;
E=[3 1];
% Create auxiliary fucntion
mydot=#(x,y)(f(x,y).*E(1)+g(x,y).*E(2));
% work
int = integral2(mydot,0,3,1,5);

Creating array handles for function that returns vector of polynomial expressions

I am trying to use the numerical integration function 'integral'
I created a function of four polynomial functions
[x; x^2; x^3; x^4]
now I want to integrate this vector row by row using the integral function.
I tried making a function handle for the function and passed it to the 'integral' function
function f = test(x)
f = [x,x^2,x^3,x^4];
end
However, I get the following error when calling it command line:
test_var=#test
integral(test_var,0,1)
Error using ^
One argument must be a square matrix and the other must be a scalar.
Use POWER (.^) for elementwise power.
Error in test (line 2)
f = [x,x^2,x^3,x^4];
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
According to the documentation of integral:
q = integral(fun, xmin, xmax)
For a scalar-valued function fun you need to define the function so that it accepts vector input and produces vector output.
For scalar-valued problems, the function y = fun(x) must accept a vector argument, x, and return a vector result, y. This generally means that fun must use array operators instead of matrix operators. For example, use .* (times) rather than * (mtimes).
If you have a vector-valued function fun you need to use the input flag 'ArrayValued':
Set this flag to true to indicate that fun is a function that accepts a scalar input and returns a vector, matrix, or N-D array output.
and in that case the requirement in item 1 above is not necessary:
If you set the 'ArrayValued' option to true, then fun must accept a scalar and return an array of fixed size.
So, you need to add the input flag 'ArrayValued' to indicate that you have a vector-valued function:
f = #(x) [x; x^2; x^3; x^4]; % or [x; x.^2; x.^3; x.^4];
integral(f, 0, 1, 'ArrayValued', true) % or integral(#f, 0, 1, 'ArrayValued', true)
% if f is defined in a file
gives
ans =
0.500000000000000
0.333333333333333
0.250000000000000
0.200000000000000

How can MATLAB use the inputdlg function to process a symbolic function input?

I'm using MATLAB R2016b - student edition to develop an m-file which takes as input a symbolic differential equation, f(t,y), and outputs a slope field and solution curve based on an initial condition. The code is
prompt={'dy/dt =','tspan','y0 ='};
title='Slope Field Calculator';
answer=inputdlg(prompt,title);
tspan = str2num(answer{2}); %#ok<*ST2NM>
y0 = str2double(answer{3});
syms t y
f = symfun(sym(answer{1}),[t,y]);
[t,y] = ode45(f, tspan, y0);
hold on
dirfield(f,-5:.3:5,-5,.3:5)
plot(t,y,'b','LineWidth',2)
The dirfield(f,-5:.3:5,-5:.3:5) function has input f as an # function, or an inline function, or the name of an m-file with quotes. The dirfield function then plots a direction field for a first order ODE of the form y' = f(t,y) using t-values from t1 to t2 with spacing of dt and using y-values from y1 to y2 with spacing of dy.
According to MATLAB help, the ode45 function solves differential equations.
[TOUT,YOUT] = ode45(ODEFUN,TSPAN,Y0) with TSPAN = [T0 TFINAL] then integrates the differential equation y' = f(t,y) from time T0 to TFINAL with initial conditions Y0. The input ODEFUN is a function handle. For a scalar T and a vector Y, ODEFUN(T,Y) must return a column vector corresponding to f(t,y).
When I run the code, the dialogue box runs nicely and accepts my inputs. But when I click "OK", the code throws this error:
Warning: Support of character vectors that are not valid variable names or
define a number will be removed in a
future release. To create symbolic expressions, first create symbolic
variables and then use operations on them.
> In sym>convertExpression (line 1559)
In sym>convertChar (line 1464)
In sym>tomupad (line 1216)
In sym (line 179)
In SlopeFieldsSolutionCurves (line 9)
Undefined function 'exist' for input arguments of type 'symfun'.
Error in odearguments (line 59)
if (exist(ode)==2)
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options,
varargin);
Error in SlopeFieldsSolutionCurves (line 10)
[t,y] = ode45(f, tspan, y0);
Where am I going wrong?
ode45 takes a function handle, not a symbolic function. Use matlabFunction instead:
[t,y] = ode45(matlabFunction(f), tspan, y0);
To get rid of the first warning, you need to define f a bit differently:
f = evalin( symengine, answer{1} );
f = symfun( f, [t,y] );

How do I create function handle from cfit, multiply with other function handle and integrate the term?

I try to get an integral of two function handles in Matlab. The first function handle would be a weibull probability density function and the second function handle is based on a cfit I created with linear interpolation of single points.
x = 0:0.1:35;
fun1 = #(x) wblpdf(x,weibullAlpha,weibullBeta);
fun2 = #(x) feval(cfitObject,x);
fun3 = #(x) (fun(x).*fun2(x));
y = integral(fun3,0,35); % Using quad(fun3,0,35) doesn't work either.
I receive the following error:
Error using integralCalc/finalInputChecks (line 515)
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.
Error in integralCalc/iterateScalarValued (line 315)
finalInputChecks(x,fx);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
Error in test (line 7) % "test" is the name of the script file.
y = integral(fun3,0,35);
The problem must have to do something with "fun2" since the code works just fine with e.g.
fun2 = x.^2;
Note: if I plot fun2 with the cfitObject I don't get an error. It's also possible to integrate the function using quad().
x = 0:0.1:35;
fun2 = #(x) feval(cfitObject,x);
y = quad(fun2,0,35);
plot(x, fun2(x))
Any help is greatly appreciated!
Your code seems to be ok. Probably the problem is that fun2 cannot take vectorized input, it could be resolved by modifying fun2 (cfitObject) to be able to handle vector input or telling the software that the function in the integral is array valued:
y = integral(fun3, 0, 35, 'ArrayValued', 1);