(Matlab)用不同的输入求解方程

时间:2015-04-19 10:03:41

标签: matlab

我有一个创建matlab程序的任务,我正在寻找" switch"和"如果"任务的功能。

用户将定义任意两个变量,然后matlab将解决另一个变量。通常,我会使用"如果"考虑到不同的情景,但方程中变量的增加也会增加线的数量。

更新了演示:

% 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));

还有其他选择吗?另外,我校园里运行的matlab没有符号工具箱,所以最好避免使用它。我现在已经结束了,因为我确信有一个简单的解决方案可以解释这种情况。

进一步更新了确切的等式: 程序可以这样做,让我们说用户输入" TR"和" gamma",然后Matlab将找到" M1"。这将进一步进入后续方程式,我将得到" M2"," PR"," rhoR"," P0R"和" P1R"。此外,我意识到,由于Matlab将从上到下阅读,有没有办法解释这个?

1 个答案:

答案 0 :(得分:1)

正如我们在评论中所写的那样,如果没有符号工具箱,你尝试做的事情是非常复杂的,而且是不可行的。

我写了一个只考虑案例的hacky解决方案: 给出3个变量{TR, gamma, M1}中的2个,然后自动计算第三个变量。然后可以使用这3个变量来求解其余的方程式。

此解决方案假设您至少一次访问符号工具箱,但在使用生成的代码时不需要它。 我们首先根据以下每种情况的符号表达式生成MATLAB函数:

  • {TR, gamma}已给出,M1缺少
  • {TR, M1}已给出,gamma缺少
  • {gamma, M1}已给出,TR缺少

这会导致写入6个文件,sol_TR.mcond_TR.m等。

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

然后可以使用这些函数计算缺失的变量:

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

示例运行:

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

ans =

     0.5000    0.0669  100.0000

你当然可以建立在这个解决方案的基础上,创建一个包含所有8个变量的符号方程组。然后,您必须生成28函数,并根据给定的输入变量选择适当的函数。


但是,我不建议这条路线。尝试在需要的地方获得符号工具箱,这可以帮助您避免很多头痛。 您可以像这样使用它:

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

示例运行:

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

missing_var =

M1

ans =

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