How do I solve this equation using Python, Octave, or Matlab?
Need to be able to find the solution of x for different values of c.
How do I solve this equation using Python, Octave, or Matlab?
Need to be able to find the solution of x for different values of c.
Use Solvers
# this is an example
>>> from sympy.solvers import solve
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> solve(x ** 2 - 1, x)
[-1, 1]
As the equation has some float constants, it is probably best to use nsolve
to solve it numerically:
from sympy import Eq, log, exp, nsolve
from sympy.abc import x
c = 267
sol = nsolve(Eq(x ** 0.22 * (c * exp(-c * x ** 0.22) - 1), c * log(0.7657)), x, 1)
print(sol) # 264587674.024352
No Toolbox Required:
In MATLAB, you can use fminsearch()
to do this numerically.
The key idea is to rewrite the equation y = w
as y - w = 0
. Then, construct a convex function to guarantee you the local minima returned is indeed globally optimal, e.g. abs(y-w)
.
% Rewrite equation y = w as y - w = 0.
% Then minimize abs(y-w).
fh =@(x,c) abs((x.^(0.22)).*(c*exp(-c*(x.^(0.22)))-1) - c*log(0.7657));
c = 267;
x0 = 5; % initial guess
[x, abserr] = fminsearch(@(x) fh(x,c),x0) % x = 264587674.0243530
Note that abserr = 4.2633e-14
which is pretty darn close to zero (equality).
Similarly, you could minimize the sum of squared error to achieve the same answer.
% minimize sum((y-w).^2)
gh =@(x,c) sum(((x.^(0.22)).*(c*exp(-c*(x.^(0.22)))-1) - c*log(0.7657)).^2);
[x, sse] = fminsearch(@(x) fh(x,c),x0)
Rather than using arrayfun()
, to get the different x
values for each c
value, it is probably easier just to loop through.
C = [100 267 300].';
Xval = zeros(size(C));
for ii = 1:length(C)
Xval(ii) = fminsearch(@(x) fh(x,C(ii)),x0);
end
Not Recommended:
While fzero()
will also work to solve y - w = 0
, notice that it aborts searching for an interval containing a sign change (if x
is negative). So you either have to add a penalty for that direction somehow, or try from a different starting value.
% solve y-w==0
zh =@(x,c) (x.^(0.22)).*(c*exp(-c*(x.^(0.22)))-1) - c*log(0.7657)
Using the same starting point,
x = fzero(@(x) zh(x,c),x0)
returns the error
Exiting fzero: aborting search for an interval containing a sign change because complex function value encountered during search. (Function value at -1.4 is 70.4499-0.686399i.) Check function or try again with a different starting value. x = NaN
while
x = fzero(@(x) zh(x,c),2e8) % adjusted starting guess
works just fine.
Tested with MATLAB R2019a