david
david

Reputation: 15

Finding solution to function in python. Error: math domain error

The code below is fine except for the fCf function. The program runs in two for loop where the i-value increments in the outside loop, consequently the V_ratio & Re values get calculated according to the second (ii) loop iterations (thus, a lot of Re & V_ratio values for a single i value). I keep getting the this error for the one function in my loop:

For 2'nd for loop code:

for ii in tau_analysis:

    fLam = root_scalar(fLambda, args=(ii, C_v, Clo), method='toms748', bracket=[0.0, 10.0])
    #print("lambda = ", fLam.root)

    Cld = 0.012 * pow(fLam.root, 0.5) * pow(ii, 1.1)
    #print("Cld =", Cld)

    V_ratio = sqrt(1 - (Cld - 0.0065 * beta * pow(Cld, 0.6)) / (fLam.root * 
              cos(math.radians(ii))))
    #print("V_ratio =", V_ratio)

    Fn = i/sqrt(g*pow(delta_volume, 1/3))                                                                  
    Re = (V_ratio*i*fLam.root*b)/visco                                                                     
    #print("Fn =", Fn)
    #print("Reynolds =", Re)

    Cf = root_scalar(fCf, args = Re, method='toms748', bracket=[0,0.01])
    print("Cf = ", Cf.root)

Function code:

def fCf(x, Re):
    return log10(Re*x) - 0.02/sqrt(x)

When I do this in MATLAB I get no errors.

error code:

Traceback (most recent call last):
  File "C:\Users\27835\PycharmProjects\pythonProject\Savitsky (3).py", line 87, in <module>
    Cf = root_scalar(fCf, args = Re, method='toms748', bracket=[0,0.01])
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_root_scalar.py", line 249, in root_scalar
    r, sol = methodc(f, a, b, args=args, **kwargs)
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1373, in toms748
    result = solver.solve(f, a, b, args=args, k=k, xtol=xtol, rtol=rtol,
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1220, in solve
    status, xn = self.start(f, a, b, args)
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1108, in start
    fa = self._callf(a)
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1082, in _callf
    fx = self.f(x, *self.args)
  File "C:\Users\27835\PycharmProjects\pythonProject\Savitsky (3).py", line 40, in fCf
    return log10(Re*x) - 0.02/sqrt(x)
ValueError: math domain error

Upvotes: 1

Views: 59

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60554

In MATLAB:

>> log10(-1)
ans =
   0.0000 + 1.3644i

>> sqrt(-1)
ans =
   0.0000 + 1.0000i

In Python:

>>> math.log10(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> math.sqrt(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

MATLAB properly handles negative inputs to both the logarithm and the square root, returning complex values. In Python these are real-valued functions, with a limited domain.

Instead, use the cmath module for complex arithmetic:

>>> cmath.log10(-1)
1.3643763538418412j
>>> cmath.sqrt(-1)
1j

It is also possible that x is 0. In this case, in MATLAB,

>> log10(0)
ans =
  -Inf

but in Python,

>>> math.log10(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> cmath.log10(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

I don't know of a simple way to solve this other than special-casing:

>>> x = 0
>>> math.log10(x) if x > 0 else -math.inf
-inf

Upvotes: 2

Related Questions