当我给它测试单个输入时,我有一个似乎正常工作的函数,但是我需要它来处理很多不同的变量。现在在底部,它评估函数的初始猜测为25,索引为50.在玩它的时候,我注意到索引实际上是在fsolve运行时进行的,所以我认为我有对fsolve如何在这里实际运行的不完全理解,但我无法修复它。我的最终目标是,我能够在for循环中将索引从1循环到54,并且在该循环内,初始猜测将根据我已经运行的算法而改变。所以我只需要解决这个函数输入问题。
这是我的代码:
function [objfun] = RK_solver( RK_solver_input )
% Redlich/Kwong EOS
index = RK_solver_input(2)
sigma = 1;
epsilon = 0;
omega = 0.08664;
psi = 0.42748;
beta = omega * RK_solver_input(1) / (Input_Data(2)/1.01325) / Tr(index);
alpha = (Tr(index))^(-1/2);
q = psi*alpha/omega/Tr(index);
A = (sigma + epsilon - 1)*beta - 1;
B = (sigma*epsilon - sigma - epsilon)*(beta^2) + (q - sigma - epsilon)*beta;
C = -(sigma*epsilon*(1+beta) + q)*(beta^2);
Q = ((A^2) - 3*B)/9;
R = (2*(A^3) - 9*A*B + 27*C)/54;
M = R^2 - Q^3;
if M < 0
theta = acos(R/(sqrt(Q*Q*Q)));
Z(1) = -2*(Q^0.5)*(cos(theta/3)) - (A/3);
Z(2) = -2*(Q^0.5)*(cos((theta + 2*pi)/3)) - (A/3);
Z(3) = -2*(Q^0.5)*(cos((theta - 2*pi)/3)) - (A/3);
Z_liquid = min(Z);
Z_vapor = max(Z);
I_liquid = (1/(sigma-epsilon))*log((Z_liquid+sigma*beta)/(Z_liquid+epsilon*beta));
I_vapor = (1/(sigma-epsilon))*log((Z_vapor+sigma*beta)/(Z_vapor+epsilon*beta));
ln_phi_liquid = Z_liquid - 1 - log(Z_liquid - beta) - q*I_liquid;
ln_phi_vapor = Z_vapor - 1 - log(Z_vapor - beta) - q*I_vapor;
objfun = (ln_phi_liquid - ln_phi_vapor);
end
end
RK_solver_guess = [25 50];
Psat_RK_solved = fsolve(@RK_solver, RK_solver_guess)
答案 0 :(得分:3)
您看到的问题是因为fsolve
假定它可以将指定为second input的任何参数更改为fsolve
。在您的示例中,您将索引作为此初始猜测的一部分传递,因此fsolve
包括优化中的索引。因此,fsolve
正在尝试修改您的真实参数(如您所愿)以及索引以尝试最小化该函数。
相反,您需要将索引指定为 函数的输入,但不作为fsolve
的参数在最小化中使用。
您可以通过修改匿名功能来实现此目的
% Can be whatever you want them to be
guesses = rand(54, 1);
for index = 1:numel(guesses)
solution(index) = fsolve(@(guess)RK_solver(guess, index), guesses(index));
end
如果您分解该匿名函数,您会看到fsolve
将提供guess
变量,然后我会将index
变量自身添加到函数调用{{ 1}}。
显然,您还需要稍微修改函数定义,以将参数和索引作为两个参数而不是向量来处理。
RK_solver