Error: Limits of integration must be double or single scalars. While solving equations numerically with symbolic integral limits
显示 更早的评论
Problem Description:
The equation system to be solved {f1=0, f2=0, f3=0} contains variables pl and pr. The expressions for pl and pr involve integrals with variables as their limits (indicated by bold parts in the code). After processing through matlabFunction to create anonymous functions, "int" is replaced with "integral". However, "integral" does not support variables as limits, resulting in an error:
Error using integral
Limits of integration must be double or single scalars.
Potentially useful reference:
This is a similar problem I found, but I can't understand it...
Problem Code:
++++++++++++++++++++++++++
alph=pi*15/180;
L=0.116;
T_ice=18;
addweight=0.212;
T0=15;
dL=0.02;
tilt=0;
heightofweight=12.5;
forcefromcable=0;
mu_L=0.001;
rho_S=920*0.95;
rho_L=1000;
Cp_s=2049.41;
h_m=334000+Cp_s*T_ice;
K_L=0.57;
P_e=102770;
g1=addweight*9.8;
g2=0.38*9.8;
heightofmasscenter=0.07;
heightofcable=0.13;
syms x1 y1 x Uratio
d = pi*L*sin(alph)/2;
M = g1*(dL+heightofweight*tan(tilt))*cos(tilt)+g2*heightofmasscenter*sin(tilt)-forcefromcable*heightofcable*sin(tilt);
G = g1+g2;
beta = atan(x1/y1);
xL = sqrt(x1^2+y1^2)*cos(pi-alph-beta);
DL = sqrt(x1^2+y1^2)*sin(pi-alph-beta);
xR = sqrt(x1^2+y1^2)*cos(beta-alph);
DR = sqrt(x1^2+y1^2)*sin(beta-alph);
LL = DL^2+(xL-x)^2;
RR = DR^2+(xR-x)^2;
C = Uratio*(int(x*RR^2,x,0,L)-int(x*LL^2,x,0,-L))/(int(LL^1.5,x,0,-L)-int(RR^1.5,x,0,L));
P0 = 12*mu_L*rho_S^4*h_m^3*Uratio^3*(Uratio*int(LL^2*x,x,0,-L)+C*int(LL^1.5,x,0,-L))/(rho_L*T0^3*K_L^3)+P_e;
pl = -12*mu_L*rho_S^4*h_m^3*Uratio^3*(Uratio*int(LL^2*x,0,x)+C*int(LL^1.5, 0,x))/(rho_L*T0^3*K_L^3)+P0;
pr = -12*mu_L*rho_S^4*h_m^3*Uratio^3*(Uratio*int(RR^2*x,0,x)+C*int(RR^1.5, 0,x))/(rho_L*T0^3*K_L^3)+P0;
% Perform definite integrals on pl and pr to obtain the target equation system
f1 = int(pl*x,x,-L,0)+int(pr*x,x,0,L)+M/d;
f2 = int(pl,x,-L,0)*sin(alph+tilt)+int(pr,x,0,L)*sin(alph-tilt)-G/d-2*L*P_e*sin(alph)*cos(tilt);
f3 = int(pl,x,-L,0)*cos(alph+tilt)-int(pr,x,0,L)*cos(alph-tilt)+2*L*P_e*sin(alph)*sin(tilt);
% Proceed with solving
% Initial guess for variables
initial_guess = [0.5, 0.1, 2];
% Define solving function
equations = matlabFunction(f1,f2,f3, 'Vars', {x1, y1, Uratio});
% Use fsolve to solve the equation system
result = fsolve(@(vars) equations(vars(1), vars(2), vars(3)), initial_guess);
++++++++++++++++++++++++++
15 个评论
Dyuman Joshi
2023-8-6
Please attach the parameter definition section as well.
Yuting
2023-8-6
C and P0 are missing.
The limit of the integrals
pl = ...int(LL^2*x,0,x)+C*int(LL^1.5, 0,x)...;
pr = ...int(RR^2*x,0,x)+C*int(RR^1.5, 0,x)...;
must be a fixed double, not a symbolic variable. Or is the limit of integration also a solution variable which should appear as "Vars" in the call to "matlabFunction" ?
Yuting
2023-8-6
Torsten
2023-8-6
I don't know where this error message comes from, but setting
equations = matlabFunction([f1,f2,f3], 'Vars', {[x1, y1, Uratio, x]});
would mean that you want to solve for 4 variables with 3 equations. This will not be possible with "fsolve".
Walter Roberson
2023-8-6
Solving 3 equations in 4 variables will not typically fail in fsolve. If it were the other way around, more variables than equations, that would typically fail
Yuting
2023-8-6
In this case, set up your complete problem numerically with no symbolic variables and "integral2".
initial_guess = [0.5, 0.1, 2];
% Use fsolve to solve the equation system
result = fsolve(@(vars) fun(vars(1), vars(2), vars(3)), initial_guess);
function res = fun(x1,y1,Uratio)
alph=pi*15/180;
L=0.116;
T_ice=18;
addweight=0.212;
T0=15;
dL=0.02;
tilt=0;
heightofweight=12.5;
forcefromcable=0;
mu_L=0.001;
rho_S=920*0.95;
rho_L=1000;
Cp_s=2049.41;
h_m=334000+Cp_s*T_ice;
K_L=0.57;
P_e=102770;
g1=addweight*9.8;
g2=0.38*9.8;
heightofmasscenter=0.07;
heightofcable=0.13;
d = pi*L*sin(alph)/2;
M = g1*(dL+heightofweight*tan(tilt))*cos(tilt)+g2*heightofmasscenter*sin(tilt)-forcefromcable*heightofcable*sin(tilt);
G = g1+g2;
beta = atan(x1/y1);
xL = sqrt(x1^2+y1^2)*cos(pi-alph-beta);
DL = sqrt(x1^2+y1^2)*sin(pi-alph-beta);
xR = sqrt(x1^2+y1^2)*cos(beta-alph);
DR = sqrt(x1^2+y1^2)*sin(beta-alph);
LL = @(x)DL^2+(xL-x).^2;
RR = @(x)DR^2+(xR-x).^2;
...
res = [f1;f2;f3]
end
I still cannot understand your integrals.
Assume for a moment
LL = DL^2+(xL-x)^2;
pl = int(LL^2*x,0,x)
f1 = int(pl*x,x,-L,0)
How would f1 look like in a mathematical notation as a double integral ?
Walter Roberson
2023-8-7
pl and pr have int() calls that are missing the variable of integration. The variable that will be assumed is not necessarily going to be the one you want.
Yuting
2023-8-7
Yuting
2023-8-7
采纳的回答
更多回答(1 个)
Walter Roberson
2023-8-6
1 个投票
integral() can never accept symbolic integration limits.
If you are trying to build up a symbolic algorithm that is later to be used with matlabFunction(), then code the integral() as either int() or vpaintegral()
Note: integral() does not accept expressions such as pl*x . The first parameter to integral() must be a function handle.
4 个评论
Yuting
2023-8-6
Walter Roberson
2023-8-6
pl = -12*mu_L*rho_S^4*h_m^3*Uratio^3*(Uratio*int(LL^2*x,0,x)+C*int(LL^1.5, 0,x))/(rho_L*T0^3*K_L^3)+P0;
Notice that you have x as an upper bound there.
f1 = int(pl*x,x,-L,0)+int(pr*x,x,0,L)+M/d;
and that int() with x as an upper bound is nested within a second int over x.
equations = matlabFunction(f1,f2,f3, 'Vars', {x1, y1, Uratio});
when matlabFunction() converts those int() into calls to integral(), it is not especially smart about it. It creates something with roughly the form
integral(@(x) expression+integral(@(x)second_expression, 0, x), 0, 0.116)
so one integral() is calling another, and the second one is using the variable of the first as the upper bound.
However, by default, integral() passes in a vector of values -- so x is a vector at the time it is received by the inner integral() call that tries to use it as the upper bound. That's a problem since the bounds can only be scalar.
What can you do?
Well, if you were tell matlabFunction to write to a 'file' and were to edit the code slightly, you could edit the outer integral() call to specify 'ArrayValued', true as its options. That would cause it to pass scalar x to the anonymous function, and so the upper bound of the inner integral() would end up being a scalar.
But to fix this automatically without doing that kind of editting... is a bit of a nuisance.
Walter Roberson
2023-8-6
Note by the way you have
equations = matlabFunction(f1,f2,f3, 'Vars', {x1, y1, Uratio});
but that should be
equations = matlabFunction([f1,f2,f3], 'Vars', {x1, y1, Uratio});
Also I suggest you consider using
equations = matlabFunction([f1,f2,f3], 'Vars', {[x1, y1, Uratio]});
as that would allow you to
result = fsolve(equations, initial_guess);
Yuting
2023-8-6
类别
在 帮助中心 和 File Exchange 中查找有关 Conversion Between Symbolic and Numeric 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!