Reputation: 151
I have this formula that I use to calculate Vo given Ps AND it can be re-arranged for Ps given Vo:
Vo=(Ps)*(BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd
I want to make a versatile function for this purpose in MATLAB. I start by declaring a symbolic function and solving it with numerical substitutions this way:
syms Ps BWc BWs Ro n LdB Rpd;
Vo(Ps,BWc,BWs,Ro,n,LdB,Rpd)=(Ps)*(BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd;
Vo(250,0.12,1000,0.01,4,0.5,75)
I want to be able to re-arrange the symbolic function for Ps and solve again:
Ps(Vo,BWc,BWs,Ro,n,LdB,Rpd)= solve('Vo=(Ps)*(BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd','Ps');
Ps(0.0063,0.12,1000,0.01,4,0.5,75)
However the above two lines do not work. I get the error for the last line above: "Operands to the || and && operators must be convertible to logical scalar values." I have also tried:
syms Vo Ps BWc BWs Ro n LdB Rpd;
Vo(Ps,BWc,BWs,Ro,n,LdB,Rpd)=(Ps)*(BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd;
Vo(250,0.12,1000,0.01,4,0.5,75)
Ps(Vo,BWc,BWs,Ro,n,LdB,Rpd)=(Vo)/((BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd);
Ps(0.0063,0.12,1000,0.01,4,0.5,75)
What is the correct way to use the symbolic toolbox for this purpose?
Upvotes: 0
Views: 640
Reputation: 18484
The issue may be because you have a variable called Vo
and you're also using Vo
to define a function. You can't do that and still use both. It's effectively an issue of variable scope. Here's how you can successfully use solve
:
syms Vo Ps BWc BWs Ro n LdB Rpd;
Vo_fun(Ps,BWc,BWs,Ro,n,LdB,Rpd) = Ps*(BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd
Vo_fun(250,0.12,1000,0.01,4,0.5,75)
Ps_fun(Vo,BWc,BWs,Ro,n,LdB,Rpd) = solve(Vo==Vo_fun,Ps)
Ps_fun(0.0063,0.12,1000,0.01,4,0.5,75)
I don't see the need to use symbolic math at all in this case. Simple anonymous functions would suffice, e.g.:
Vo = @(Ps,BWc,BWs,Ro,n,LdB,Rpd)(1/10^((LdB*(2*n + 3))/10)*BWc*Ps*Ro*Rpd)/BWs;
Ps = @(Vo,BWc,BWs,Ro,n,LdB,Rpd)(10^((LdB*(2*n + 3))/10)*BWs*Vo)/(BWc*Ro*Rpd);
Note that there is no problem with scope here in the naming of the functions. If the other arguments aren't changing, you can make these just a function of Vo
and Ps
:
BWc = ...
BWs = ...
Ro = ...
n = ...
LdB = ...
Rpd = ...
Vo = @(Ps)(1/10^((LdB*(2*n + 3))/10)*BWc*Ps*Ro*Rpd)/BWs;
Ps = @(Vo)(10^((LdB*(2*n + 3))/10)*BWs*Vo)/(BWc*Ro*Rpd);
Or you could create a single regular function that handles either input:
function out=VoPs(name,value,BWc,BWs,Ro,n,LdB,Rpd)
if (ischar(name) && strcmp(name,'Ps')) || (isa(name,'sym') && logical(name==sym('Ps')))
Ps = value;
Vo = Ps*(BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd;
elseif (ischar(name) && strcmp(name,'Vo')) || (isa(name,'sym') && logical(name==sym('Vo')))
Vo = value;
Ps = Vo/((BWc/BWs)*Ro*(10^((-(3+2*n)*LdB)/10))*Rpd);
else
error('VoPs:InvalidName','Name input must be ''Vo'' or ''Ps''.')
end
Upvotes: 0