Pregunta

I have a system of three symbolic equations:

(1) Ua  = (Un*Ga -ia -(U2 -Ug2)*G3)/Ga;
(2) U2  = (Ug2*G3 -(Uc2m - Ua)*Ca*Fs)/(Ca*Fs + G3);
(3) Ug2 = ((Ua -Uc2m)*Ca*Fs* G3 -ig2*(Ca*Fs + G3)) / ((G3 + Gg2)*(Ca*Fs + G3) - G3*G3);

After substitutions of (3) inside (2) and (1), and then (2) inside (1), I have (1) as follows:

Ua  = (Un*Ga -ia -((((Ua -Uc2m)*Ca*Fs* G3 -ig2*(Ca*Fs + G3)) / ((G3 + Gg2)*(Ca*Fs + G3) - G3*G3)*G3 -(Uc2m - Ua)*Ca*Fs)/(Ca*Fs + G3) -((Ua -Uc2m)*Ca*Fs* G3 -ig2*(Ca*Fs + G3)) / ((G3 + Gg2)*(Ca*Fs + G3) - G3*G3))*G3)/Ga;

With Ua appearing both on the left and on the right member. Is there a way (with Matlab or any other tool) to:

  1. Simplify the expression having only Ua on the left
  2. Starting from the original system of three symbolic equations, simplify all of them automatically specifying what symbols consitute the three variables (that will appear on the left), and consider the rest as parameters to leave on the right.
¿Fue útil?

Solución 2

I'm not sure all of @RodyOldenhuis's hard work is required in this case. It's simply a matter of using solve correctly. When you provide N equations, it's usually best to ask for it to solve for N variables either of your choosing of its own (by not specifying any variable names):

syms Ua Ug2 U2 ia Un Ga G3 Uc2m Ca Fs ig2 Gg2
eqs = [Ua == (Un*Ga -ia -(U2 -Ug2)*G3)/Ga
       U2 == (Ug2*G3 -(Uc2m -Ua)*Ca*Fs)/(Ca*Fs + G3)
       Ug2 == ((Ua -Uc2m)*Ca*Fs*G3 -ig2*(Ca*Fs + G3)) / ((G3 + Gg2)*(Ca*Fs + G3) -G3*G3)];

s = solve(eqs,Ua,U2,Ug2)

Then s.Ua returns

-(G3*Gg2*ia - G3*Ga*Gg2*Un + Ca*Fs*G3*ia + Ca*Fs*G3*ig2 + Ca*Fs*Gg2*ia - Ca*Fs*G3*Gg2*Uc2m - Ca*Fs*G3*Ga*Un - Ca*Fs*Ga*Gg2*Un)/(G3*Ga*Gg2 + Ca*Fs*G3*Ga + Ca*Fs*G3*Gg2 + Ca*Fs*Ga*Gg2)

Don't make the mistake of passing in Ua, U2, and Ug2 into solve as a vector (unless you're using R2015a+, I believe).

This works using the old string-based technique as well (the cell array could be replace by individual strings inputs if desired):

eqs = {'Ua = (Un*Ga -ia -(U2 -Ug2)*G3)/Ga'
       'U2 = (Ug2*G3 -(Uc2m -Ua)*Ca*Fs)/(Ca*Fs + G3)'
       'Ug2 = ((Ua -Uc2m)*Ca*Fs*G3 -ig2*(Ca*Fs + G3)) / ((G3 + Gg2)*(Ca*Fs + G3) -G3*G3)'};

s = solve(eqs{:},'Ua','U2','Ug2')

This works in R2013a and R2015a. I don't know if older versions can handle this or not.

Otros consejos

Intuitively I'd say just do solve(expr1, expr2, expr3, 'Ua'), but that doesn't seem to work, (at least on R2010a)...

So I got hacking. Now, I'm not much of a symbolic toolbox guy, so there's quite likely a "better" way to do this. Nevertheless, the following function answers both your questions:

function solution = solveFor(exprs, var)

    %// Split the equations up into the RHS and LHS
    C = regexp(expr, '\s*=\s*', 'split');
    C = cat(1, C{:});

    %// The equation we're solving for 
    kk = find(strcmp(C(:,1), var));

    %// Substitute every expression into every other expression
    for ii = 1:size(C,1)
        if ii==kk, continue; end

        for jj = 1:size(C,1)
            if jj==ii, continue; end

            C{jj,2} = regexprep(C{jj,2}, C{ii,1}, C{ii,2});
        end
    end

    %// Solve for the requested variable & simplify
    solution = simplify(solve([C{kk,1} '=' C{kk,2}], C{kk,1}));

end

Use like this:

>> expr{1} = 'Ua  = (Un*Ga -ia -(U2 -Ug2)*G3)/Ga';
>> expr{2} = 'U2  = (Ug2*G3 -(Uc2m - Ua)*Ca*Fs)/(Ca*Fs + G3)';
>> expr{3} = 'Ug2 = ((Ua -Uc2m)*Ca*Fs*G3 - ig2*(Ca*Fs + G3)) / ((G3 + Gg2)*(Ca*Fs + G3) - G3*G3)'; 
>> Ua = solveFor(expr, 'Ua')
Ua = 
    -(G3*Gg2*ia - G3*Ga*Gg2*Un + Ca*Fs*G3*ia + Ca*Fs*G3*ig2 + Ca*Fs*Gg2*ia - Ca*Fs*G3*Gg2*Uc2m - Ca*Fs*G3*Ga*Un - Ca*Fs*Ga*Gg2*Un)/(G3*Ga*Gg2 + Ca*Fs*G3*Ga + Ca*Fs*G3*Gg2 + Ca*Fs*Ga*Gg2)

Obvious limitations:

  • all equations must be in the form above, e.g., 'single variable = expression'
  • equations must be given as strings and thus cannot be the outcome of other smybolic operations (although using expr = cellfun(@char, expr, 'UniformOutput', false); at the top would cancel that restriction)

EDIT

The call to solve that works has the following syntax:

S = solve(expr{:}, 'Ua,U2,Ug2');

So, to automate the process, you can modify the function above to the following simpler form:

function solution = solveFor(exprs, var)

    %// Syms or strings?
    if ~iscellstr(exprs) && all(cellfun('isclass', exprs, 'sym'))
        exprs = cellfun(@char, expr, 'UniformOutput', false); 
    else
        error(...);
    end

    %// Split the equations up into the RHS and LHS
    C = regexp(expr, '\s*=\s*', 'split');
    C = cat(1, C{:});

    %// Solve for the requested variables
    vars = cellfun(@(x)[x ','], C(:,1), 'UniformOutput', false);
    vars = [vars{:}];
    solution = solve(expr{:}, vars(1:end-1));

    %// Extract desired solution
    solution = simplify(solution.(var));

end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top