简体   繁体   中英

New to Python, don't know what is wrong with my code

I'm new to Python so please be gentle.

I seriously don't know what is wrong with my code.

Here it is:

import numpy as np

def epsilon(t):
    epsilon = (1 - np.exp(-pow(t, 4)))
    return epsilon

def r(t):
    r = pow( (epsilon(t) - 16) / 4, 1/4)
    return r

print(r(0))

Since epsilon(0) = 0 , I'd expect (analytically) to get r = (-16/4)^(1/4) = (-1)^(1/4)*sqrt(2) = exp(i pi /4)*sqrt(2) = 1 + 1 i

But instead I get:

RuntimeWarning: invalid value encountered in double_scalars
  r = pow((4 * epsilon(t) - 16) / 4, 1/4)
nan

I've tried to find the error. If I print epsilon(0) I get 0 as expected, and If i set epsilon(0) manually like:

def r(t):
    r = pow( 0 - 16) / 4, 1/4)
    return r
print(r(0))

I get 1 + 1 j . And If I remove the to the power of 1/4 , it works and I get -4

import numpy as np

def epsilon(t):
    epsilon = (1 - np.exp(-pow(t, 4)))
    return epsilon

def r(t):
    r = (epsilon(t) - 16) / 4
    return r

print(r(0))

So why do

import numpy as np

def epsilon(t):
    epsilon = (1 - np.exp(-pow(t, 4)))
    return epsilon

def r(t):
    r = pow( (epsilon(t) - 16) / 4, 1/4)
    return r

print(r(0))

I get this error?

Problem is probably caused by the numpy float thing. (as aswered by Schomes). Fix by convert to 'normal' float.

import numpy as np

def epsilon(t):
    epsilon = (1 - np.exp(-pow(t, 4)))
    return epsilon

def r(t):
    epsi_boy = epsilon(t)
    print(type(epsi_boy)) # numpy float
    epsi_boy = float(epsi_boy) # Convert to non numpy float
    r = pow( (epsi_boy - 16) / 4,  1/4)
    return r

print(r(0))

I noticed that the value returned by epsilon() is of type <class 'numpy.float64'> . The problem occurs when we include this value in Python's built in pow() function. For example, try pow(np.float64(-4.0), 1/4) ; it breaks too. Perhaps it's due to this:

With mixed operand types, the coercion rules for binary arithmetic operators apply. Built-in Functions: pow()

I managed to fix the issue by casting the result of epsilon() to float .

r = pow( float((epsilon(t) - 16) / 4), 1/4) .

The reason is numpy float64 are like c float, and overload all operations (including) power to work as such. This is the type returned by exp and subsequently in all operations. Note you're trying to compute:

(-4)**(1/4)

which is an imaginary number. Python can handle that, and output the result, but numpy float64 s are "real", so the above is an invalid expression. For this reason all the answers here suggesting to convert to float work:

>>> (-4)**(1/4)
(1.0000000000000002+1j)
>>> np.float64(-4)**(1/4)
__main__:1: RuntimeWarning: invalid value encountered in double_scalars
nan
from math import exp
def epsilon(t):
    epsilon = (1 - exp(-pow(t, 4)))
    return epsilon


def r(t):
    print(2)
    t=epsilon(t)
    r = pow( ( t- 16) / 4, 1/4)
    return r

print(r(0))

Or

from numpy import exp
def epsilon(t):
    epsilon = (1 - exp(-pow(t, 4)))
    return epsilon


def r(t):
    print(2)
    t=epsilon(t)
    r = pow( float( t- 16) / 4, 1/4)
    return r

print(r(0))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM