135

I was just testing an example from Numerical Methods in Engineering with Python.

from numpy import zeros, array
from math import sin, log
from newtonRaphson2 import *

def f(x):
    f = zeros(len(x))
    f[0] = sin(x[0]) + x[1]**2 + log(x[2]) - 7.0
    f[1] = 3.0*x[0] + 2.0**x[1] - x[2]**3 + 1.0
    f[2] = x[0] + x[1] + x[2] -5.0
    return f
    
x = array([1.0, 1.0, 1.0])
print(newtonRaphson2(f,x))

When I run it, it shows the following error:

File "example NR2method.py", line 8, in f
    f[0] = sin(x[0]) + x[1]**2 + log(x[2]) - 7.0
ValueError: math domain error

I have narrowed it down to the log as when I remove log and add a different function, it works. I assume it is because of some sort of interference with the base, I can't figure out how. Can anyone suggest a solution?


See also: Python math domain error using math.acos function for the equivalent problem using math.acos; python math domain error - sqrt for the equivalent problem using math.sqrt.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
ramanunni.pm
  • 1,619
  • 2
  • 11
  • 9

5 Answers5

172

Your code is doing a log of a number that is less than or equal to zero. That's mathematically undefined, so Python's log function raises an exception. Here's an example:

>>> from math import log
>>> log(-1)
Traceback (most recent call last):
  File "<pyshell#59>", line 1, in <module>
    log(-1)
ValueError: math domain error

Without knowing what your newtonRaphson2 function does, I'm not sure I can guess where the invalid x[2] value is coming from, but hopefully this will lead you on the right track.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • I don't see how it is doing a negative log as the definition is defining the set of equations, that is, x[0], x[1] and x[2] are variables x,y and z which Newton Raphson uses. It needs these set of equations to solve. – ramanunni.pm Apr 08 '13 at 23:11
  • 1
    Also, as I am saying x[2] = 1.0 when I define x in the code above, log(1) = 0, atleast that is what I though, maybe I am wrong.. Thanks for the help though.. – ramanunni.pm Apr 08 '13 at 23:18
  • 2
    add a `print x` to the beginning of your function **f**. Youll get to see how the equation solver successively tries different values of x, leading to your error. – mtadd Apr 08 '13 at 23:28
  • 3
    In my cases the problem was the argument was not negative, but exactly equal to 0, which leads to the same exception (which might be surprising for people with JS background, where Math.log(0) is simply -Infinity) – qbolec Aug 03 '16 at 08:33
4

You may also use math.log1p.

According to the official documentation :

math.log1p(x)

Return the natural logarithm of 1+x (base e). The result is calculated in a way which is accurate for x near zero.

You may convert back to the original value using math.expm1 which returns e raised to the power x, minus 1.

Catalina Chircu
  • 1,506
  • 2
  • 8
  • 19
4

you are getting math domain error for either one of the reason : either you are trying to use a negative number inside log function or a zero value.

Physics3067
  • 57
  • 1
  • 6
3

We face this problem when we use log() or sqrt() from math library. In this problem “math domain error”, we are using a negative number like (-1 or another) or a zero number where we should not be use.

2

You are trying to do a logarithm of something that is not positive.

Logarithms figure out the base after being given a number and the power it was raised to. log(0) means that something raised to the power of 2 is 0. An exponent can never result in 0*, which means that log(0) has no answer, thus throwing the math domain error

*Note: 0^0 can result in 0, but can also result in 1 at the same time. This problem is heavily argued over.

Eric Xue
  • 272
  • 2
  • 11