Weird problem of matlab when using coeffs and collect - matlab

Here is the code.
expr = 3/z + 2*z^2 + 7*z^3;
[cx,tx] = coeffs(expr)
This below is the error mesage.
Error using symengine Polynomial expression expected.
Error in sym/mupadmexnout (line 1177)
out = mupadmex(fcn,args{:});
Error in sym/coeffs (line 62)
[cSym,tSym] = mupadmexnout('symobj::coeffsterms', p, args{:});
Another problem when using collect.
syms t z
sympref('PolynomialDisplayStyle','ascend');
a = 5;
n(t) = taylor(cos(t),t,'ExpansionPoint',pi,'Order',a);
s1(t) = taylor(1/(t^2),t,'ExpansionPoint',pi,'Order',a);
s2(t) = 1/(t-pi)^3;
nu(z) = subs(n, t-pi, z)
s(z) = expand(subs(s1 * s2, t-pi, z));
laurent(z) = expand(nu * s)
expr = 3/z + 2*z^2 + 7*z^3;
coeffs_z = collect(laurent,z)
$$\frac{-5,z^8 +{\left(4,\pi \right)},z^7 +{\left(60-3,\pi^2 \right)},z^6 +{\left(2,\pi^3 -48,\pi \right)},z^5 +{\left(36,\pi^2 -\pi^4 -120\right)},z^4 +{\left(96,\pi -24,\pi^3 \right)},z^3 +{\left(12,\pi^4 -72,\pi^2 \right)},z^2 +{\left(48,\pi^3 \right)},z-24,\pi^4 }{{\left(24,\pi^6 \right)},z^3 }$$
It has the denominator 24pi^6z^3. How can I get rid of this denominator?

From the error message:
Error using symengine Polynomial expression expected.
From the documentation:
C = coeffs(p) returns coefficients of the polynomial p with respect to
all variables determined in p by symvar.
The expression expr = 3/z + 2*z^2 + 7*z^3; is not a polynomial (3/z is not on the form a*z^n for n>=0).
The rest of the question is a separate question and should be in a different post.

Related

Error when taking gradient of symbolic function

I get an error when taking the gradient of a symbolic function. Can anyone tell me why I get this error?
syms x1 x2 R
L0=0; %[m]
k1=8; %[N/m]
k2=4; %[N/m]
F1=5; %[N]
F2=10; %[N]
F = 0.5*k1*(sqrt(x1^2 + (L0-x2)^2) - L0)^2 + 0.5*k2*(sqrt(x1^2 + (L0+x2)^2)
- L0)^2 - F1*x1 - F2*x2;
f = matlabFunction(F);
R = 0.1;
GI = x1^2 + x2^2 - R^2;
gi = matlabFunction(GI);
epsilon=0.001;
xo=[0,0]';
k = 0;
r = (sqrt(5)-1) / 2;
rpe=0.01;
Merit_pe = #(x1,x2) f(x1,x2) + rpe*(max(0,gi(x1,x2)))^2;
g = gradient(Merit_pe, [x1 x2]);
Error:
Error using sym/max (line 97)
Input arguments must be convertible to
floating-point numbers.
Error in
Ex>#(x1,x2)f(x1,x2)+rpe*(max(0,gi(x1,x2)))^2
Error in sym>funchandle2ref (line 1249)
S = x(S{:});
Error in sym>tomupad (line 1154)
x = funchandle2ref(x);
Error in sym (line 163)
S.s = tomupad(x);
Error in sym/gradient (line 17)
args = privResolveArgs(sym(f));
Error in Ex (line 31)
g = gradient(Merit_pe, [x1 x2])
I think the max part is causing me trouble, but I still need to determine the gradient of this function. Any advise? (I could do it by hand I guess, but I'd rather not if I don't have to)
Directly taking the gradient of max(0,gi(x1,x2)) is not possible in matlab. Instead the function should be defined according to the following definition.
The function Merit_pe can then be defined as follows:
if gi(xo(1,1),xo(2,1)) > 0
Merit_pe = #(x1,x2) f(x1,x2) + rpe*(gi(x1,x2))^2;
else
Merit_pe = #(x1,x2) f(x1,x2);
end
The gradient can then be determined using:
g = gradient(Merit_pe, [x1 x2]);

Bisection Method: Unable to use functions and how to handle multiple function inputs [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I had a working bisection method but I need to implement it in a function that will take three arguments: f the function being used, xL the left side of the boundary, and xR the right side of the boundary. Furthermore it has to have the ability to change the function based on the value of x (if the function was f(x) for example). if x is less than or equal zero, f(x) will be x^3 + 3x + 1, if x is greater that zero then f(x) will be 1 + sin(x). The function needs to output the root and the number of iterations performed
How can I pass a function for f is the function arguments, and then how can I find the value of x to determine which function to use?
Here are the errors I am getting along with the console input:
>> f = inline('x^3 + 3x + 1', 'x')
f =
Inline function:
f(x) = x^3 + 3x + 1
>> bisectionF(f,-2,0.1)
Undefined function or variable 'bisectionF'.
>> bisectionF(f,-2,0.1)
Undefined function or variable 'B'.
Error in bisectionF (line 3)
maxIters = 20;B
>> bisectionF(f,-2,0.1)
Error using inlineeval (line 14)
Error in inline expression ==> x^3 + 3x + 1
Error: Unexpected MATLAB expression.
Error in inline/feval (line 33)
INLINE_OUT_ = inlineeval(INLINE_INPUTS_, INLINE_OBJ_.inputExpr, INLINE_OBJ_.expr);
Error in bisectionF (line 7)
fM = feval(f,xM);
>> y = bisectionF('f1',-2,0.1)
Error using feval
Undefined function 'f1' for input arguments of type 'double'.
Error in bisectionF (line 9)
fM = feval(f,xM);
>> f1 = inline('x^3 + 3x + 1', 'x');
>> root = bisectionF(f1,-2,0.1)
Error using inlineeval (line 14)
Error in inline expression ==> x^3 + 3x + 1
Error: Unexpected MATLAB expression.
Error in inline/feval (line 33)
INLINE_OUT_ = inlineeval(INLINE_INPUTS_, INLINE_OBJ_.inputExpr, INLINE_OBJ_.expr);
Error in bisectionF (line 9)
fM = feval(f,xM);
Here is my code:
function[r, iters] = bisectionF(f,xL,xR)
%f1 = inline('x^3 + 3x + 1', 'x');
%f2 = inline('1+sin(x)','x');
maxIters = 20;
precision = 10^(-5);
for j = 1:maxIters
xM=(xL + xR)/ 2;
fM = feval(f,xM);
fL = feval(f,xL);
fR = feval(f,xR);
if fM * fL < 0
xR = xM
elseif fM * fR < 0
xL = xM;
end
if abs(fM) < precision
disp(['Iterations performed: ', num2str(j)])
disp('Convergence was reached')
elseif(j==20)
disp('The maximum number of iterations were performed')
end
r = xM;
iters = j;
end
You can pass as input not just an inline function, but a set (cell) of inlines. In your main script (or in the Command Window) you can declare such cell array as follows:
f1 = inline('x^3 + 3*x + 1', 'x');
f2 = inline('1+sin(x)','x');
CandidateFunctions{1}=f1;
CandidateFunctions{2}=f2;
and give CandidateFunctions as input to bisectionF (instead of a single function f).
Inside bisectionF now, after the line
xM=(xL + xR)/ 2;
you can set an if/else switch:
if xM<=0
f=CandidateFunctions{1}
else
f=CandidateFunctions{2}
end
In this manner you reassign/overwrite f at each iteration, depending on whether xM is positive, negative or null.

Using MATLAB integral with anonymous functions

I'm trying to use the MATLAB integral() function to integrate along a single parameter of a piecewise linear function that represents a time-varying value.
I would like to define an anonymous function based on the original function:
t1 = 1;
t2 = 2;
t3 = 4;
t4 = 5;
a0 = 1;
a1 = 2;
f = #(x) accel_profile(t1,t2,t3,t4,a0,a1,x);
and here is the accel_profile.m:
function value = accel_profile(t1,t2,t3,t4,a0,a1, t)
if t <= t1
value = a0;
return
elseif (t <= t2)
value = ((t-t1)/(t2-t1)) * (a1-a0) + a0;
return
elseif (t <= t3)
value = a1;
return
elseif (t <= t4)
value = ((t-t3)/(t4-t3)) * (a0-a1) + a1;
return
else
value = a0;
return
end
The problem is that when I exercise the following script:
t_list = 0:0.1:6;
q = zeros(1,length(t_list))
for i = 1:length(t_list)
q(i) = integral(f,0,t_list(i));
end
plot(t_list, q)
I get the following stack trace:
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);
515 error(message('MATLAB:integral:FxNotSameSizeAsX'));
I'm running MATLAB 2015b on Windows 7.
The problem is integral uses vectorized arguments for your function, but your function does not support it.
The relevant part from the documentation:
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 set the 'ArrayValued' option to true, then fun must accept a scalar and return an array of fixed size.
Reference
This means integral will call your function f with arguments like f([1,2,3]) and expects a list with [f(1),f(2),f(3)]
The general techniques to vectorize a piecewise defined function are explained in this question

Error using mtimes

I'm trying to run this function like this: calcSQNRA(0,4,6) and I'm getting these errors:
??? Error using ==> mtimes Inner matrix dimensions must agree.
Error in ==> calcSQNRA>#(x)x.^2*e.^(-x) at 6 f = #(x) x.^2 * e.^(-x);
Error in ==> quadl at 70 y = feval(f,x,varargin{:}); y = y(:).';
Error in ==> calcSQNRA at 7 x = 10 * log10(3 * 4^t *
quadl(f,xmin,xmax));
function [x] = calcSQNRA(xmin, xmax, N)
e = exp(1);
t = log2(N);
f = #(x) x.^2 * e.^(-x);
x = 10 * log10(3 * 4^t * quadl(f,xmin,xmax));
The function is trying to compute the SQNR of an exponential distribution (if I thought of it correctly), after a uniform quantization. Note that if I erase the e.^(-x) from f it actually produces a result. Any ideas?
I kill 15 minutes debugging quadl and feval functions. And going so deep in this process I just think about this simple thing:
it just works if I set . in your f anonymous function this way:
f = #(x) x.^2 .* e.^(-x);
then
calcSQNRA(0,4,6) give result: 22.1635.
Is it what you want to achieve?

Solving a system of 5 nonlinear equations in Matlab

I'm having difficulty using the fsolve function to solve a set of 5 equations in Matlab.
Here are the 5 equations:
y = a + d + e
y + x = c + d + 2e
2x = 4a + 2b + 2c
k1 = (d * b^3 / (a * c) ) * ((P/Pref)/(a+b+c+d+e))^2
k2 = be/(dc)
y,x,k1,k2,P,Pref are all parameters that I set, but would like to leave them in the function so that I can change them quickly in my code to find new answers. a,b,c,d,e are the variables that I'd like to solve for (they are compositions of a reaction equilibrium equation)
I tried to hard code the parameters in the function, but that didn't work. I'm just not sure what to do. Every thing I change creates a new error. The most common is that the data type has to be "double".
Edit: adding code
first the function:
function F = myfun(Q,I)
a = Q(1);
b = Q(2);
c = Q(3);
d = Q(4);
e = Q(5);
x = I(1);
y = I(2);
k1 = I(3);
k2 = I(4);
P = I(5);
Pref = I(6);
F(1) = a + d + e - y;
F(2) = c + d + 2*e - y - x;
F(3) = 4*a + 2*b + 2*c - 2*x;
F(4) = ((d * b^3)/(a*c))*((P/Pref)/(a+b+c+d+e))^2 - k1;
F(5) = (b*e)/(c*d);
next is the program:
%Q = [a,b,c,d,e]
%I = [x,y,k1,k2,P,Pref]
%The values for the inputs will be changed to vary the output
%Inputs:
x=5;
y=1;
k1=5;
Pref=1;
P=1;
k2=-0.01;
syms K
k1 = solve(log10(k1) - k1);
syms L
k2 = solve(log10(k2) - k2);
x = double(x);
y = double(y);
Pref = double(Pref);
P = double(P);
k1 = double(k1);
k2 = double(k2);
%Solving:
I = [x,y,k1,k2,P,Pref];
q = [0,0,0,0,0]; %initial guess
Q = fsolve(#myfun,[q,I])
when I run this, these errors comes up:
Error using myfun (line 7)
Not enough input arguments.
Error in fsolve (line 218)
fuser = feval(funfcn{3},x,varargin{:});
Error in Coal (line 27)
Q = fsolve(#myfun,[q,I])
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot continue.
Edit 2: changed the fsolve line, but still got errors:
Error using trustnleqn (line 28)
Objective function is returning undefined values at initial point. FSOLVE cannot continue.
Error in fsolve (line 376)
[x,FVAL,JACOB,EXITFLAG,OUTPUT,msgData]=...
Error in Coal (line 27)
fsolve(#(q) myfun(q,I),q)
Edit3: changed a couple parameters and the initial guess, I am now getting an answer, but it also comes up with this:
Solver stopped prematurely.
fsolve stopped because it exceeded the function evaluation limit,
options.MaxFunEvals = 500 (the default value).
ans =
0.0000 2.2174 3.7473 1.4401 3.8845
how can I get it to not stop prematurely?
Re: how can I get it to not stop prematurely?
Pass non-default options in your call to fsolve.
Refer to the signature, fsolve(myfun,q,options) here,
http://www.mathworks.com/help/optim/ug/fsolve.html
And read about creating the options using optimoptions here,
http://www.mathworks.com/help/optim/ug/optimoptions.html
You should be able to get it to "not stop prematurely" by increasing the values of convergence criteria such as TolFun and TolX.
However, it's advisable to read up on the underlying algorithms you're relying upon to perform this numerical solution here,
(EDIT: I tried to fix non-linky links, but I'm not allowed to provide more than two ... Boo) www.mathworks.com/help/optim/ug/fsolve.html#moreabout
The error you received simply indicates that after 500 function evaluations the algorithm has not yet converged on an acceptable solution conforming to the default solver options. Just increasing MaxFunEvals may allow the algorithm extra iterations needed to converge within default tolerances. For example,
options = optimoptions('MaxFunEvals',1000); % try something bigger than 500
fsolve(#(q) myfun(q,I),q,options);