1
votes

I have a task of creating a matlab program, and I was searching for "switch" and "if" functions for the task.

And the user will define any two of the variables, then matlab will solve for the other one. Normally, I would use "if" to account for different scenarios, but the increasing number of variables in the equation would increase the number of lines as well.

Updated with a demonstration:

% Mach Number after Shockwaves
M2=sqrt((((gamma-1).*M1.^2)+2)./(2*gamma.*M1.^2-(gamma-1)));

% Temperature Ratio
TR=((2*gamma.*M1.^2-(gamma-1)).*(((gamma-1).*M1.^2)+2))./(((gamma+1)^2).*M1.^2);

% Pressure Ratio
PR=(2*gamma.*M1.^2-(gamma-1))./(gamma+1);

% Density Ratio
rhoR=((gamma+1).*M1.^2)./(((gamma-1).*M1.^2)+2);

%Stagnant Pressure Ratio Before Shockwaves
P0R=(((1+0.2.*M2.^2)./(1+0.2.*M1.^2)).^(1.4/0.1)).*((2*gamma.*M1.^2-(gamma-1))./(gamma+1));

%Stagnant Pressure Ratio After Shockwaves
P1R=((1+0.2.*M2.^2).^(1.4/0.4)).*((2*gamma.*M1.^2-(gamma-1))./(gamma+1));

Is there any alternative? Also, the matlab running in my campus has no symbolic toolbox, so it would best to avoid it. I am at my wit's end now, for I am sure there is a simple solution to account for such scenario.

Further Updated with the exact equation: The program will be able to do like, let's say the user enter "TR" and "gamma", and then Matlab will find the "M1". This would further be carried into subsequent equations, where I would get "M2","PR","rhoR","P0R" and "P1R". Also, I realised that since Matlab will read from top to bottom, is there any way to account for this?

1
It would help if you add your code - Konstantin
do you only need to support linear equations? then have a look at mathworks.com/help/matlab/ref/linsolve.html - m.s.
Added a simple code to demonstrate my problem. @m.s. But could "linsolve" allows matlab to solve for the variable automatically, given the inputs from users? - Jethro
is the example equation the only one you need to cover? if yes, then the calculation does not depend on whether x and y, or x and z, or y and z are given: result = -a-b; you should give more contextual information where you need this etc. - m.s.
Do you need to call them X, Y, Z? Or can it be canged? - Btc Sources

1 Answers

1
votes

As we already wrote in the comments, what you try to do is very complicated and rather infeasible without the symbolic toolbox.

I have written a hacky solution which only accounts for the case: 2 out of the 3 variables {TR, gamma, M1} are given, the third one is then automatically calculated. These 3 variables can then be used to solve the remaining equations.

This solution assumes that you have at least once access to the symbolic toolbox, but you won't need it when you use generated code. We first generate MATLAB functions based on the symbolic expression for each of the following cases:

  • {TR, gamma} given, M1 missing
  • {TR, M1} given, gamma missing
  • {gamma, M1} given, TR missing

This results in 6 m-files to be written, sol_TR.m, cond_TR.m, etc.

syms gamma M1 TR;
assume(gamma, 'real');
assume(gamma > 0);

assume(M1, 'real');
assume(M1 > 0);

assume(TR, 'real');
assume(TR > 0);

eq = TR ==(((gamma - 1)*M1^2 + 2)*(2*gamma*M1^2 - gamma + 1))/(M1^2*(gamma + 1)^2);

vars = {gamma, M1, TR};
num_vars = size(vars,2);

for i=1:num_vars
    current_var = vars{i};
    [sol, ~, cond] = solve(eq,current_var, 'ReturnConditions', true);
    matlabFunction(sol, 'File', sprintf('sol_%s',char(current_var)),'Vars', vars, 'Optimize', false);
    matlabFunction(cond, 'File', sprintf('cond_%s',char(current_var)),'Vars', vars, 'Optimize', false);
end

These functions can then be used to calculate the missing variable:

function [input_vector] = calc_third(varname_1, var_value_1, varname_2, var_value_2)

     varnames = {'gamma', 'M1', 'TR'};
     num_vars = size(varnames,2);
     var_index = 1:num_vars;
     var_name_map = containers.Map(varnames,var_index);

     input_vector = zeros(1,num_vars);
     input_vector(var_index == var_name_map(varname_1)) = var_value_1;
     input_vector(var_index == var_name_map(varname_2)) = var_value_2;

     var_index(var_index == var_name_map(varname_1)) = [];
     var_index(var_index == var_name_map(varname_2)) = [];

     sol_func = sprintf('sol_%s(input_vector(1),input_vector(2),input_vector(3))', varnames{var_index});
     cond_func = sprintf('cond_%s(input_vector(1),input_vector(2),input_vector(3))', varnames{var_index});
     result = dot(eval(sol_func), eval(cond_func));

     input_vector(var_index)= result;
end

Example run:

>> calc_third('gamma', 0.5, 'TR', 100) 

ans =

     0.5000    0.0669  100.0000

You could of course build upon that solution and create a symbolic system of equations which incorporates all your 8 variables. You would then have to generate 28 functions and select the approriate ones based on the given input variables.


However, I would not recommend that route. Try to get the symbolic toolbox where you need it, this should help you avoid a lot of headache. You could use it then like this:

function [] = calc_third(varname_1, var_value_1, varname_2, var_value_2)

    gamma = sym('gamma');
    M1 = sym('M1');
    TR = sym('TR');

    eq = TR ==(((gamma - 1)*M1^2 + 2)*(2*gamma*M1^2 - gamma + 1))/(M1^2*(gamma + 1)^2);

    subs_eq = (subs(eq,[sym(varname_1), sym(varname_2)],[var_value_1,var_value_2]));

    missing_var = symvar(subs_eq)

    solve(subs_eq,missing_var)

end

Sample run:

>> calc_third('gamma', 0.5, 'TR', 100)

missing_var =

M1

ans =

(2*2^(1/2))/(3*88609^(1/2) + 893)^(1/2)