1

How do I solve this equation using Python, Octave, or Matlab?

equation

Need to be able to find the solution of x for different values of c.

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
sharib ahmed
  • 114
  • 10
  • 1
    Welcome to stackoverflow! Please be sure to check out [how to ask good questions](https://stackoverflow.com/help/how-to-ask) for ideas on how to make this more complete and better formatted. As is, I'm not sure what you're asking, and the content being behind an image makes it very hard to search for. – David Mar 10 '20 at 18:27
  • Is `c` restricted to the condition `c ≥ 0`? It seems that at if `c > 0` solutions exist, and for `c = 0`, then `x = 0` by inspection. However, negative values of `c` appear problematic. – SecretAgentMan Mar 10 '20 at 21:22

3 Answers3

3

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]
Michael Mior
  • 28,107
  • 9
  • 89
  • 113
  • I tried solving for c=1 but the editor has thrown this error. "No algorithms are implemented to solve equation x + log(1 - 267/(1000*x))" – sharib ahmed Mar 10 '20 at 18:08
  • try this : from sympy.solvers import nsolve /// from sympy import Symbol, log /// x = Symbol('x') /// nsolve(x + log(1 - 267/(1000*x)), x,1) – Zouhair Elhadi Mar 10 '20 at 18:40
3

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
JohanC
  • 71,591
  • 8
  • 33
  • 66
3

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

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41