How to use solve() with max()
5 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Hello, I am trying to solve() the equation pictured for "A" (Actually, A = L*H, and I am trying to solve for L. Known: M, H, beta, const. Unknown: L)
I have tried the following code:
syms L W M
M = 6; H = 15;
eqn = [log10(L*H)+(2/3)*log10(max(1,sqrt(L*H/H^2))/((1+max(1,L*H/(H^2*7.4)))/2))+3.98 == M];
vars = [L H M];
[solv, solu] = solve(eqns, vars)
But I receive an error: "Error using symengine Input arguments must be convertible to floating-point numbers."
I think the error is from the max() terms.
I tried a test re-writing as piecewise()
syms L W M
M = 6; W = 15;
eqn = [log10(L*W)+(2/3)*log10(piecewise(sqrt(L*W/W^2) > 1, sqrt(L*W/W^2), 1)/((piecewise(L*W/(W^2*7.4) >1, L*W/(W^2*7.4), 1))/2))+3.98 == M];
vars = [L W M];
[solv, solu] = solve(eqn, vars)
And receive the following error: "Error using sym.getEqnsVars>checkVariables (line 92)Second argument must be a vector of symbolic variables."
I'm sure I'm missing something that should be obvious, but any help would be appreciated--thx!
0 Kommentare
Antworten (1)
Walter Roberson
am 24 Feb. 2018
piecewise is the correct approach.
In the second case you are asking to solve a single equation in the single variable L with respect to the variable L and the constants 15 and 6. You cannot solve with respect to numeric constants. When you assign a numeric value to a variable it loses its previous identity as being symbolic. If you had not assigned constants to those variables then you would not have gotten that error, but you would still be trying to solve a single equation with respect to 3 variables.
4 Kommentare
Walter Roberson
am 26 Feb. 2018
Revised code for the case where I also declare M and W to be real:
syms L
syms M W nonnegative real
Q = @(v)sym(v,'r');
eqn = [log10(L*W)+(Q(2)/3)*log10(piecewise(sqrt(L*W/W^2) > 1, sqrt(L*W/W^2), 1)/((piecewise(L*W/(W^2*Q(7.4)) >1, L*W/(W^2*Q(7.4)), 1))/Q(2)))+Q(3.98) == M];
sol = solve(eqn, L, 'returnconditions', true);
%now try specific values
solL = subs(sol.L, [M, W], [6, 15]);
solcond = subs(sol.conditions, [M,W], [6,15]);
ncond = length(solcond);
param = sol.parameters;
solz = cell(ncond,1);
if isempty(param)
valid_z_mask = simplify(solcond);
valid_L = solL(valid_z_mask) %in this case you can be sure it will be a vector
else
for K = 1 : ncond
thiscond = solcond(K);
solz{K} = solve(thiscond, param);
end
valid_z_mask = ~cellfun(@isempty, solz);
valid_L = arrayfun(@(L,Zcell) subs(L, Zcell{1}), solL(valid_z_mask), solz(valid_z_mask), 'uniform', 0) %in this case the number of results for each case is uncertain
end
There are two paths here.
Without the 'real', the original solve() returns a vector of values, each with an associated condition, and with one of the values parameterized by an extra variable whose value needs to be determined later. The general flow for this is to solve for each possible value of the extra variable and substitute that value back into the solutions for L. But for any particular M and W value, some of the potential values might be ruled out, giving an empty solution, so you need to do some filtering on the solution set of L.
With the 'real' in place, the original solve() returns a vector of values, each with an associated condition, but already has enough information that no extra variables are needed. In this case with no auxillary variable, when you substitute particular numeric values into the conditions, you get a vector of true and false values as to whether the condition is fulfilled, and you can use that to filter the list of solutions for L.
Siehe auch
Kategorien
Mehr zu Conversion Between Symbolic and Numeric finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!