-2

I want to find the the root of Nonlinear Function. So, I use fsolve method in scipy.optimize library. But, it doesn't work.

The name of the variable with the root of Nonlinear Function is "s". With the variable 's', I want to find the other variable values. I appreciate if you help me.

Code

# calculate I0 with new Rp value

from sympy import Symbol, solve, exp
import sympy as sp
from scipy.optimize import fsolve

I02 = (Isc \* (1 + Rs1 / Rp) - Voc / Rp) / (np.exp(Voc / vt1) - np.exp(Rs1 \* Isc / vt1));
Ipv2 = I02 \* ((np.exp(Voc / vt1)) - 1) + Voc / Rp;
ImpC = Pmax / VmpC;
err = abs(Imp - ImpC);
Rpnew = Rp;
while ((err \> toll) & (itI \< iter)) :
if ImpC \< Imp :
Rpnew = Rp + 0.1 \* itI;
else :
Rpnew = Rp - 0.1 \* itI;

    print(itI);
    # Calculate I0 with rpnew
    I02 = (Isc * (1 + Rs1 / Rpnew) - Voc / Rpnew) / (np.exp(Voc / vt1) - np.exp(Rs1 * Isc / vt1));
    print(I02);
    Ipv2 = I02 * ((np.exp(Voc / vt1)) - 1) + Voc / Rpnew;
    print(Ipv2);
    
    x = sp.symbols('x');
    eqn = Ipv2 - (I02 * (sp.exp((Vmp + (Rs1 * x)) / vt1) - 1)) - x - (Vmp + Rs1 * x) / Rpnew;
    print(eqn);
    print(type(eqn));
    
    current_c = Imp;
    print(current_c);
    
    s = fsolve(func = eqn, x0 = current_c);
    print(s);
    ImpC = s;
    itI = itI + 1;
    err = abs(Imp - ImpC);

Traceback Massage

TypeError                                 Traceback (most recent call last)
Cell In \[65\], line 43
40 print(current_c);
41 # s = fzero(eqn,current_c);
42 # s = sp.solveset(eqn, x);
\---\> 43 s = fsolve(func = eqn, x0 = current_c);
44 print(s);
45 ImpC = s;


TypeError: 'Add' object is not callable'
Jun
  • 1
  • 1
  • 1
    Welcome to Stack Overflow. Please read [ask] and https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ and [mre]. Note well that we don't provide a debugging service here. Before posting, you are expected to do your own work to figure out *where* the problem seems to occur, and *what* seems to be causing it. Try to simplify the code by taking out working parts of the program. For example, do you need to **do anything besides** set the value of `eqn`, and then attempt `s = fsolve(func = eqn, x0 = current_c)`, to cause the problem? Can you write a simpler `eqn` and still cause it? – Karl Knechtel Jan 10 '23 at 02:34
  • As an aside: Python does not require semicolons at the end of lines, and they are generally considered poor style. – Karl Knechtel Jan 10 '23 at 02:35
  • `eqn` is a `sympy` expression. It cannot be used as a function argument to `scipy` `fsolve`. Don't try to mix `sympy` and `numpy/scipy` - at least not until you know both much better. That includes understanding what python means by `callable`. – hpaulj Jan 10 '23 at 03:17
  • I'm reopening this, since the proposed `duplicate` is not useful. https://stackoverflow.com/questions/35468985/integrals-in-python-add-object-not-callable. My comment about not using `scipy` with `sympy` expression still applies. Apparently the OP did check the `type` of `epn`, but forgot to check the `fsolve` docs. – hpaulj Jan 10 '23 at 16:31

1 Answers1

0

Obviously since you did not show the definition of many variables, I can't recreate it. But I can make a simple expression:

In [2]: epn = x-y  
In [3]: epn
Out[3]: 
x-y

You checked the type of epn (but didn't show it!), so you know that it is a sympy.Add object:

In [4]: type(epn)
Out[4]: sympy.core.add.Add

And some reading of sympy basics should make it clear that an expression is NOT a python function. That is it is NOT callable:

In [5]: epn(1,2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[5], line 1
----> 1 epn(1,2)

TypeError: 'Add' object is not callable

The docs for scipy fsolve clearly say that the first argument:

func: callable f(x, *args)

You have two options - create a python function that can be used in fsolve. If x is the only variable (symbol) that shouldn't be hard. I notice you use a mix of np.exp and sp.exp. Why?

The other option is to use a sympy solver.

As a general rule mixing sympy and scipy/numpy is not a good idea. lambdify can sometimes be used to convert a sympy expression into a python function. But perhaps more importantly you need to read the sympy docs to get a clearer idea of how its objects - symbols and expressions - differ from Python variables and functions.

hpaulj
  • 221,503
  • 14
  • 230
  • 353