Hi there,
I have multiple equations which determine the values in a circuit. I'm trying get the values which satisfy these equations (maybe even with conditions like nonnegative circuit values).
This is my code but I get these errors:
Error using symengine
Input arguments must be convertible to floating-point numbers.
Error in sym/privBinaryOp (line 1030)
Csym = mupadmex(op,args{1}.s, args{2}.s, varargin{:});
Error in sym/max (line 78)
C = privBinaryOp(X, Y, 'symobj::zipWithImplicitExpansion', 'symobj::maxComplex');
Error in Class_E (line 4)
eqn2 = C1==max(0, 1/(2*pi*RFfreq*R_L)*K_C-1.088E-12);
I really appreciate any help you can provide.
Best,
Safak
syms RFfreq R_L V_DD P_out C1 C2 L1 L2 K_P K_C K_X K_L
eqn1 = R_L==V_DD*V_DD/P_out*K_P;
eqn2 = C1==max(0, 1/(2*pi*RFfreq*R_L)*K_C-1.088E-12); %take 0 or what the right side equatates to (if nonzero)
eqn3 = C2==C_0;
eqn4 = L2==L_0+R_L/(2*pi*RFfreq)*K_X;
eqn5 = L1==R_L/(2*PI*RFfreq)*K_L;
eqn6 = K_L==1E6;
eqn7 = K_C==0.1836;
eqn8 = K_P==0.5768;
eqn9 = K_X==1.152;
eqn10 = V_DD==17;
eqn11 = P_out==15;
eqn12 = RFfreq==3.5E9;
eqn13 = C_0==1E-09;
eqn14 = L_0==1/(2*PI*RFfreq)^2/C_0;
eqns = [eqn1 eqn2 eqn3 eqn4 eqn5 eqn6 eqn7 eqn8 eqn9 eqn10 eqn11 eqn12];
sol=solve(eqns)

3 Comments

is PI equal to pi ?
Yes, I could just use pi there, right? Code is from Keysight's ADS. That's why it is spelled this way.
I forgot to include these:
eqn13 = C_0==1E-09;
eqn14 = L_0==1/(2*PI*RFfreq)^2/C_0;

Sign in to comment.

 Accepted Answer

Q = @(v) sym(v);
PI = Q(pi);
symmax = @(A,B) piecewise(A<=B, A, B);
syms RFfreq R_L V_DD P_out C1 C2 L1 L2 K_P K_C K_X K_L
syms C_0 L_0
eqn1 = R_L==V_DD*V_DD/P_out*K_P;
eqn2 = C1==symmax(0, 1/(2*PI*RFfreq*R_L)*K_C-Q(1.088E-12)); %take 0 or what the right side equatates to (if nonzero)
eqn3 = C2==C_0;
eqn4 = L2==L_0+R_L/(2*PI*RFfreq)*K_X;
eqn5 = L1==R_L/(2*PI*RFfreq)*K_L;
eqn6 = K_L==Q(1E6);
eqn7 = K_C==Q(0.1836);
eqn8 = K_P==Q(0.5768);
eqn9 = K_X==Q(1.152);
eqn10 = V_DD==Q(17);
eqn11 = P_out==Q(15);
eqn12 = RFfreq==Q(3.5E9);
eqns = [eqn1 eqn2 eqn3 eqn4 eqn5 eqn6 eqn7 eqn8 eqn9 eqn10 eqn11 eqn12];
sol = solve(eqns, [C1, C2, K_C, K_L, K_P, K_X, L1, L2, P_out, RFfreq, R_L, V_DD]);
sol will be a mix of constant values, together with the variables C_0 and L_0

4 Comments

Thank you so much for sharing your code.
I forgot to include these:
eqn13 = C_0==1E-09;
eqn14 = L_0==1/(2*PI*RFfreq)^2/C_0;
I don't need the split them with syms C_0 L_0 right?
How does your solution work? Especially this part
Q = @(v) sym(v);
PI = Q(pi);
symmax = @(A,B) piecewise(A<=B, A, B);
You have lines such as
eqn7 = K_C==0.1836;
and you are constructing equations to be processed using solve() . The purpose of solve() is to find indefinitely precise closed-form solutions whenever possible. In order for it to be meaningful to find indefinitely precise solutions, you need to have indefinitely precise inputs.
However, 0.1836 is not an indefinitely precise input. 0.1836 does not mean 1836/10000 exactly . In terms of constructing equations, writing 0.1836 means that at that point you have some number that you do not know the exact value of, but you know that it is between 18355/10000 (inclusive) and 18365/10000 (exclusive).
MATLAB uses IEEE 754 binary floating point to represent literal numbers that are not specifically marked as having some other interpretation. IEEE 754 says that when 0.1836 is written, that it should best be represented as the nearest 53 bit-precision value to 1836/10000 exactly. That number is 1.8360000000000000763833440942107699811458587646484375 in full precision. IEEE 754 would be happy with either of the two "adjacent" representable numbers too. So the literal number 0.1836 does not represent 1836/10000 to MATLAB: It represents 1.8360000000000000763833440942107699811458587646484375 exactly. Which is a number in the range 18355/10000 to 18365/10000 so as far as scientific notation is concerned, everything is fine.
When you have a number in your equations that you do not know the exact indefinite-precision value of, such as 0.1836, then it makes no logical sense to ask solve() to give you an indefinitely precise answer. How can you have an indefinitely precise solution to a value that is not precise?
Using floating point numbers with solve() is a "category error", a contradiction. A deliberately imprecise number in a routine that is only for finding infinitely precise solutions.
So... in order for it to be meaningful to use solve(), those floating point numbers have to be converted to indefinitely precise numbers. Which is what the function
Q = @(v) sym(v);
does: given a floating point number, it will check to see if it is "close enough" to a rational multiple of Pi, and if so will use that rational multiple. If not then it will look to see if it is "close enough" to sqrt root of a rational, and if so then will use a square-root and rational number indicator. If not then it will look to see if it is "close enough" to a nice integer ratio, and if so will use that with a rational number indicator. And if none of those, it will convert the number right out to the exact interpretation of the IEEE 754 floating point number involved.
PI = Q(pi);
Your calculation uses pi; here I say to substitute the indefinitely precise irrational number instead. This matters because once you start doing calculations with the IEEE 754 double precision approximation of pi, it does not take long before the symbolic toolbox cannot recognize the original pi anymore and starts using nasty long exact ratios that mean nothing to humans
symmax = @(A,B) piecewise(A<=B, A, B);
In the symbolic toolbox, min(A,B) with A or B containing a symbolic value, is a problem. min() and max() want to resolve immediately, to give a definite answer about which value is larger or smaller, which is something that they cannot do if an unresolved symbolic variable is involved. syms x; min(0,x) is an error because unresolved symbolic x cannot be compared to 0 and min() needs to know right now.
So in place of your min() we substitute code that the symbolic engine is happy to postpone decisions on. For the symbolic engine, that is the piecewise() construct. piecewise(A<=B, A, B) says that if at some point you can resolve A and B down to numeric values to decide on their order, then at that point you would substitute their minimum, and if you cannot tell which is smaller, then it is cool to just keep hanging around in state of indecision (until something demands that the decision be settled.) MATLAB can reason about piecewise() constructs.
Wow, thank you for this extensive and deep explanation!
Would you mind to share the script when C_0 and L_0 are given like here?
eqn13 = C_0==1E-09;
eqn14 = L_0==1/(2*PI*RFfreq)^2/C_0;
Q = @(v) sym(v);
PI = Q(pi);
symmax = @(A,B) piecewise(A<=B, A, B);
syms RFfreq R_L V_DD P_out C1 C2 L1 L2 K_P K_C K_X K_L
syms C_0 L_0
eqn1 = R_L==V_DD*V_DD/P_out*K_P;
eqn2 = C1==symmax(0, 1/(2*PI*RFfreq*R_L)*K_C-Q(1.088E-12)); %take 0 or what the right side equatates to (if nonzero)
eqn3 = C2==C_0;
eqn4 = L2==L_0+R_L/(2*PI*RFfreq)*K_X;
eqn5 = L1==R_L/(2*PI*RFfreq)*K_L;
eqn6 = K_L==Q(1E6);
eqn7 = K_C==Q(0.1836);
eqn8 = K_P==Q(0.5768);
eqn9 = K_X==Q(1.152);
eqn10 = V_DD==Q(17);
eqn11 = P_out==Q(15);
eqn12 = RFfreq==Q(3.5E9);
eqn13 = C_0==Q(1E-09);
eqn14 = L_0==1/(2*PI*RFfreq)^2/C_0;
eqns = [eqn1 eqn2 eqn3 eqn4 eqn5 eqn6 eqn7 eqn8 eqn9 eqn10 eqn11 eqn12];
eqns = subs(eqns,lhs(eqn14),rhs(eqn14));
eqns = subs(eqns,lhs(eqn13),rhs(eqn13));
vars = [C1, C2, K_C, K_L, K_P, K_X, L1, L2, P_out, RFfreq, R_L, V_DD];
sol = solve(eqns, vars);
sol.(char(lhs(eqn13))) = rhs(eqn13);
sol.(char(lhs(eqn14))) = subs(rhs(eqn14),sol);

Sign in to comment.

More Answers (1)

hosein Javan
hosein Javan on 12 Aug 2020
Edited: hosein Javan on 12 Aug 2020
you must first define the unknowns in your system of equations. it seems you have 12 equations and therefore you must have 12 unknowns. if not 12 unknowns then reduce the number of equations to the number of unknowns. then correct the final line:
% define your unknowns in a vector like this x = [x1, x2, ..., x12]
sol=solve(eqns,x)
also eqn2 has a problem. it is defined in a way to compute the max of an unknown symbolic type and a real number 0. I suggest you solve the equations two times for each one of them and see which solution meets the condition.

4 Comments

Thank you so much for your response.
1: Actually, I'm only interested in R_L, C1, C2, L1 and L2. The other equations should be treated like variables. Is this possible without changing the stucture?
2: I could just write
eqn2 = C1==1/(2*pi*RFfreq*R_L)*K_C-1.088E-12;
But if this is negative, all the other calues are computed with errors. The program should calculate R_L and use that to set C1 to a nonnegative value and proceed. How can one do that?
you're welcome. actually you didn't even need a system of equations. just define C_0 and L_0. this code already calculates R_L, C1 and L1:
K_L = 1E6;
K_C = 0.1836;
K_P = 0.5768;
K_X = 1.152;
V_DD = 17;
P_out = 15;
RFfreq = 3.5E9;
R_L = V_DD*V_DD/P_out*K_P
C1 = max(0, 1/(2*pi*RFfreq*R_L)*K_C-1.088E-12) %take 0 or what the right side equatates to (if nonzero)
L1 = R_L/(2*pi*RFfreq)*K_L
% define L_0 here
L2 = L_0+R_L/(2*pi*RFfreq)*K_X;
% define C_0 here
C2 = C_0;
What is the difference between using a system of equations and this way?
this way is way more efficient. you were using symbolic math toolbox which is dedicated for symbolic equations that are not ordinarily simple to solve or simplify by hand. furthermore your case was not a system of equations containing unknowns depending on each other. has the problem been solved yet?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!