Reputation: 13
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?
Upvotes: 1
Views: 371
Reputation: 16324
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
missingThis 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)
Upvotes: 1