Hi everyone, I am trying to perform a simple curvefitting, but Matlab keeps throwing this error message at me. Does anyone know whats the issue?
It is weird that I only encounter this problem when I try to work with the function Aufheiz6Var, but I get no issues when working with Aufheiz4var and Aufheiz2Var, they are almost exactly the same functions but just different equations.
Error using symengine
Code generation failed due to unexpected object of type
'RootOf'.
res1 = mupadmex('symobj::generateMATLAB',r.s,ano,spa,splitIt);
r = mup2mat(c{1},true,sparseMat,false);
body = mup2matcell(funs, opts.Sparse);
gs=matlabFunction(ilaplace(Zges*rect))
Error in 1515 (line 55)
bx=@(start)Aufheiz6var(Res(i-2),Res(i-1),Res(i),Cap(i-2),Cap(i-1),start,Zth,time(i,:),aufheizdauer);
Error in fminsearch (line 201)
fv(:,1) = funfcn(x,varargin{:});
if i==2
Zth=temp(i,:)/PHI;
Res(i)=Zth(aufheizdauer)-Res(i-1);
bx=@(start)Aufheiz4var(Res(i-1),Res(i),Cap(i-1),start,Zth,time(i,:),aufheizdauer);
AufheizParameter=fminsearch(bx,start);
Cap(i)=AufheizParameter;
end
if i==3
Zth=temp(i,:)/PHI;
Res(i)=Zth(aufheizdauer)-Res(i-1)-Res(i-2);
bx=@(start)Aufheiz6var(Res(i-2),Res(i-1),Res(i),Cap(i-2),Cap(i-1),start,Zth,time(i,:),aufheizdauer);
AufheizParameter=fminsearch(bx,start);
Cap(i)=AufheizParameter;
end
function A=Aufheiz6var(R1,R2,R3,C1,C2,C3,Zth,xm,aufheizdauer)
syms s
Z3=R3/(R3*C3*s+1);
Z2=(R2+Z3)/((R2+Z3)*C2*s+1);
Z1=R1+Z2;
Zges=1/(s*C1+1/Z1);
rect=(1-exp(-s*aufheizdauer))/s;
gs=matlabFunction(ilaplace(Zges*rect))
A=sum((gs(xm)-Zth).^2);
clf;
plot(xm,Zth,'b');
hold on;
plot(xm,gs(xm),'r');
drawnow
end
function A=Aufheiz4var(R1,R2,C1,C2,Zth,xm,aufheizdauer)
syms s
Z2=R2/(R2*C2*s+1);
Z1=R1+Z2;
Zges=1/(s*C1+1/Z1);
rect=(1-exp(-s*aufheizdauer))/s;
gs=matlabFunction(ilaplace(Zges*rect));
A=sum((gs(xm)-Zth).^2);
clf;
plot(xm,Zth,'b');
hold on;
plot(xm,gs(xm),'r');
drawnow
end

 Réponse acceptée

Paul
Paul le 18 Juil 2022

1 vote

I'm going to speculate that the denominator of Zges*rect in Aufheiz6Var is of too high of an order for the Symbolic Math Toolbox to be able to factor exactly as it would need to do for ilaplace(). Unless you need closed-form expressions, consider not using the SMT at all, and instead use the Control Systems Toolbox to generated the time responses.

7 commentaires

Hi Mert,
Code below illustrates comparison between Symbolic Math Toolbox and Control System Toolbox
aufheizdauer = 1; % example time delay
SMT solution
syms s
Zges_smt = simplify(Aufheiz4var(21,30,19.66,25,s));
rect = (1-exp(-s*aufheizdauer))/s;
Ysmt = rect*Zges_smt;
CST solution
s = tf('s');
Zges_cst = Aufheiz4var(21,30,19.66,25,s);
rect = (1-exp(-s*aufheizdauer))/s;
Ycst = (1 - exp(-s*aufheizdauer))/s*Zges_cst;
Compare the time responses
figure
fplot(ilaplace(Ysmt),[0 1000]);
hold on
impulse(Ycst,1000,'ro'); % let Matlab choose the time vector
rect is applying a zero-order-hold to Zges, which can also be captured by developing a discrete-time approximation using the zoh option
[y,t] = impulse(c2d(Zges_cst,aufheizdauer,'zoh'),1000,'gx');
plot(t(1:10:end),y(1:10:end),'gx')
% replot, zooming in around t = 0
figure
fplot(ilaplace(Ysmt),[0 1000]);
hold on
impulse(Ycst,1000,'ro');
[y,t] = impulse(c2d(Zges_cst,aufheizdauer,'zoh'),1000,'gx');
plot(t,y,'gx')
xlim([0 10])
function Zges = Aufheiz4var(R1,R2,C1,C2,s)
Z2 = parallel_impedance(1/(s*C2),R2);
Z1 = series_impedance(R1,Z2);
Zges = parallel_impedance(1/(s*C1),Z1);
end
function Z = series_impedance(Z1,Z2)
Z = Z1 + Z2;
end
function Z = parallel_impedance(Z1,Z2)
Z = 1/(1/Z1 + 1/Z2);
end
Mert sargin
Mert sargin le 19 Juil 2022
You are the best !
Seems like I got stuck at one point, how can I transition the impulse response into a function of t, so I can apply the least square error method for the curve fitting.
gs=impulse(Ycst,aufheizdauer)
This delivers me two vectors of size 101x1, which I couldnt figure out how to continue working with here:
A=sum((gs-Zth).^2);
This line
gs = impulse(Ycst,aufheizdauer)
should only return a single output, not two. And it's only computing the impulse response from t = 0 to t = aufheizdauer, which I doubt is the intent. And I don't know what Zth is.
Hard to say any more without seeing the complete code and some explanation as to what the code is trying to accomplish.
Mert sargin
Mert sargin le 19 Juil 2022
Modifié(e) : Mert sargin le 19 Juil 2022
I just want to take the time response and apply a least square error algorithm to it so I can continue my curve fitting.
[y,t]=impulse(Ycst,aufheizdauer)
y and t are vectors of size 101x1 which contain the significant response times and their values of the circuit of interest. Zth is the reference I want to fit for, it is a vector of size 1x80001 containing my experimental measurement data. The last capacity "C3" is going to be determined by curve fitting.
Now to be able to perform this line of code
A=sum((gs(xm)-Zth).^2);
my gs (time response) needs to be in the same format as my reference data. So, I thought the next line would return the time response of Ycst and store it in gs as a function of t. (It is intented to only get the Impulse response till "aufheizdauer" since thats the part where I am fitting)
gs=impulse(Ycst,aufheizdauer)
When working with the SMT this line
gs=matlabFunction(ilaplace(Zges*rect));
returned me an expression of the time response in the form of a function of t, where I was simply able to calculate the difference of each sample point and apply the least square error method, since it was a plain "int - int" operation. (If I am wrong here correct me please, I am not sure regarding the syntax of this expression : "gs(xm)-Zth" since gs(xm) is a sample point and Zth is a 1x80001 Vector)
A=sum((gs(xm)-Zth).^2);
From what I understand, you must have a time vector of 1 x 800001 that pairs up with the elements of Zth. Let's call this time vector Tth. Is Tth equally spaced?
If it is, then you can do
y = impulse(YCst,Tth);
to get the values of y at the corresponding value of Tth, assuming the spacing of the elements of Tth is small enough relative to the dynamics of Ycst.
If Tth is not equally spaced, you can try to compute the impulse response of Ycst and then interpolate it to values of Tth, as shown below allowing Matlab to select the time vector for the impulse response (or you can specify yourself) and using the default linear interpolation (which you can also change).
[y,t] = impulse(Ycst,Tth(end));
y = interp1(t,y,Tth);
I still don't understand why aufheizdauer would get into the call to impulse, unless aufheizdauer = TTh(end).
If you want to go down the symbolic path using matlabFunction, you can try to use vpa to get past the rootOf issue
syms s t
y(t) = ilaplace(1/(s^5 + 2*s^4 + 3*s^3 + 4*s^2 + s + 1))
y(t) = 
y(t) = vpa(y(t))
y(t) = 
vpa(y(t),5) % for visibility
ans = 
matlabFunction(y(t))
ans = function_handle with value:
@(t)exp(t.*-1.597626686280057).*8.974810715078028e-2-exp(t.*-3.197963122886144e-2).*cos(t.*5.548185101647158e-1).*2.633024724275729e-1+exp(t.*-3.197963122886144e-2).*sin(t.*5.548185101647158e-1).*5.749882554495332e-1+exp(t.*-1.6920702563111e-1).*cos(t.*1.413518888969003).*1.735543652767926e-1-exp(t.*-1.6920702563111e-1).*sin(t.*1.413518888969003).*1.09431756071144e-1
Mert sargin
Mert sargin le 19 Juil 2022
Modifié(e) : Mert sargin le 19 Juil 2022
I cant thank you enough. You are such a blessing. Its working now.

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by