Complex number Data type in Python3 - python

If I write x=5+j in python3. It shows me type(x) is an int. why this
not considered as a complex number?

You forgot write number before j if you write 5+1j and check type you get what you want (complex type), like below:
x = 5+1j
type(x)
#complex
For define complex numbers you can use different approaches.
You can use np.complex like below:
import numpy as np
x = np.complex(5,1)
type(x)
# complex
print(x)
# (5+1j)
Also You can use cmath:
import cmath
x = complex(5,1)
type(x)
# complex
print(x)
# (5+1j)

You could use the cmath module which allows you to work with complex numbers.
A very simple example of usage:
import cmath
x = 5 + 1*1j
# alternatively
# x = complex(5,1)
print(type(x))
print(x)
Check out more: https://docs.python.org/3/library/cmath.html
It's a standard package, so you don't have to install anything.

The fact that type(x) is int probably means that you already have a variable j in your code, and that variable is an int. Just like this:
>>> j = 10
>>> x = 5 + j
>>> type(x)
<class 'int'>
Now, if you wish to create a complex number, you may either use the built-in complex function:
>>> x = complex(5, 1)
>>> x
(5+1j)
>>> type(x)
<class 'complex'>
or write a literal complex number:
>>> x = 5 + 1j
>>> x
(5+1j)
>>> type(x)
<class 'complex'>
The main difference between this and what you wrote is that 5 + j means "5 plus a variable called j", whereas 5 + 1j means "5 plus the complex number 1j". Remember that j is not the imaginary unit, it is the name of a variable. If you wish to write a complex literal, you need to write something like <number>j. In particular, the imaginary unit can be written as 1j.

Related

Protected Division Using Sympy

A protected division is a normal division but when you divide by 0 it returns a fixed constant (usually 1).
def protected_div(x, y):
if y == 0:
return 1
return x/y
Is there a way to use this as an operator on sympy (For example replacing the standard division)?
Here is an example of what I want:
>>> import sympy as sym
>>> x = sym.Symbol('x')
>>> expr = 1/x #(protected division goes here?)
>>> expr.subs(x, 0)
1
The division has to be protected at evaluation time.
EDIT 1:
What I've tried:
1.
Using sym.lambidify with the modules parameter set:
>>> x = sym.Symbol('x')
>>> expr = 1/x
>>> lamb = sym.lambdify(x, expr, modules={'/':protected_div})
>>> print(lamb(0))
ZeroDivisionError: 0.0 cannot be raised to a negative power
This does not work because sympy converts 1/x to x**(-1) when lambidifying. I tried overriding the power operator but I don't know the function name. I've tried 'Pow', 'pow', '**' and none worked.
However if i declare the expression as expr = 1.0/x it actually does not convert to a negative power, however it does not use my custom division function. I think these types of functions are not overridable using the module parameter.
2.
#Zaz suggestion:
class floatsafe(float):
def __truediv__(self, __x):
if __x == 0:
return floatsafe(1)
return super().__truediv__(__x)
x = sym.Symbol('x')
expr = floatsafe(1)/x
print(expr.subs(x, floatsafe(0)))
Returns
zoo
Which is complex infinity.
I tried combining this approach with sym.lambdify, but the dividend is converted to a float after I lambdify the function.
In the case that the dividend is variable it also does not work:
x = sym.Symbol('x')
expr = x/0.0
a = sym.lambdify(x, expr, modules={'/':floatsafe.__truediv__})
print(inspect.getsource(a))
print(a(floatsafe(0)))
Outputs
def _lambdifygenerated(x):
return nan*x
nan
EDIT: There seems to some confusion around why I'd want that. It's for a genetic programming algorithm using sympy. A protected division is a common operator in GP so that the created solutions are valid.
The regular mathematics we use on the day-to-day is a ring on the set of real numbers, ℝ: The properties of a ring are that you have two operations (such as multiplication and addition) and one of them (such as addition) will always produce another number within the set.
You can create a more specific notion of a field (such that both operations will always produce another member in the set) by removing 0 or expanding the set to the hyperreals.
My point being, without knowing what problem exactly you're trying to solve, I would guess that instead of redefining division, it makes more sense to redefine the number system that you're using: For whatever reason, you have some system of numbers that should return 1 when divided by zero, so why not create a subclass of float, for example?
class floatD01(float):
def __truediv__(self, divisor):
if divisor == 0:
return 1
return self/divisor
You may also want to scan help(float) for any other methods related to division that you may want to change such as __divmod__, __floordiv__ (7//3 == 2), etc, and have a hard think about how you want this new mathematical group that you're creating to work and why.
Other options that may potentially be more robust would be to go nuclear and try catching all ZeroDivisionErrors and replace them with one (either by modifying the class) or within whatever code you're running or, if appropriate, implementing something like what the language R extensively uses: NA values. I'm sure there's some way (I believe in numpy) to do something along the lines of: C = [1/3, 2/2, 3/1, 4/0] # == [1/3, 2/2, 3/1, NA] sum(C) = 4.333
The solution was pretty simple actually, although I was not able to actualy overload the division operator all I had to do was create a sympy function for the protected division and use that instead.
class protected_division(sym.Function):
#classmethod
def eval(cls, x, y):
if y.is_Number:
if y.is_zero:
return sym.S.One
else:
return x/y
Then just use that in an expression:
>>> expr = protected_division(1, sym.Symbol('x'))
protected_division(1, x)
>>> expr.subs(sym.Symbol('x'), 0)
1
>>> expr.subs(sym.Symbol('x'), 3)
1/3
I did not find out how to make the class tell sym.lambdify what to do in case of a "lambdification", but you can use the modules parameters for that:
>>> def pd(x, y):
... if y == 0:
... return 1
... return x/y
...
>>> l = sym.lambdify(sym.Symbol('x'), expr, modules={'protected_division': pd})
>>> l(3)
1.6666666666666667
>>> l(0)
1

sympy.simplify doesn't work on "tanh^2(x-y) + sech^2(x-y)"

I use sympy (ver1.9).
I calculate the following expressions((1)~(4)) by sympy.simplify().
All of them are expected to be identical to 1 analytically.
but (4) did not return 1, and the expression isn't simplified.
Why does this happen?
Try rewriting to exp and then simplifying:
>>> eq=tanh(x-y)**2 + sech(x-y)**2
>>> eq.rewrite(exp).simplify()
1
or use the function to rewrite hyperbolics to trigonometric functions before simplifying, e.g. with fu:
>>> from sympy.simplify.fu import hyper_as_trig
>>> e,f=hyper_as_trig(eq)
>>> f(fu(e))
1
See also hyper_as_trig in simplify/fu.py.

Python: float(var) conversion in Python wont work [duplicate]

This question already has answers here:
How do I get a decimal value when using the division operator in Python?
(13 answers)
Closed 8 years ago.
this is my code:
def pmi(w1,w2):
x = float(1)
x = (bg_fdist[(w1, w2)])/(f_brown[(w1)]*f_brown[(w2)])
print x
the values entered will be:
>>> bg_fdist[('of','the')]
9781
>>> f_brown[('of')]
36412
>>> f_brown[('the')]
6997`
so i expect my x to be very small and between 0 and 1.
but i get as a return:
>>>> pmi('of','the')
0
i assume that might be, because x gets still handled as an integer? why is this? can anyone point out how i might get my expected result?
greetings!
The x that you have declared as float(1) has nothing whatsoever to do with the result of the calculation in the second line: it was simply thrown away and replaced with the result from there. Instead, you'll need to explicitly case some of the elements of that calculation to floats.
The whole thing could be made clearer by splitting it up, like this:
def pmi(w1,w2):
first = float(bg_fdist[(w1, w2)])
second = float(f_brown[(w1)]*f_brown[(w2)])
result = first/second
return result
If you do
>>> x = float(1)
>>> x
1.0
>>> type(x)
<type 'float'>
x is indeed a float. But if after you instanciate it with an int, it's not a float anymore:
>>> x = 2
>>> x
2
>>> type(x)
<type 'int'>
When doing your division, you are using integer so:
>>> x = 2/4
>>> x
0
>>> type(x)
<type 'int'>
You still have an integer. Instead you could use float on your variable in your equation:
>>> x = float(2)/4
>>> x
0.5
You could also use from __future__ import division.
The current division (/) operator has an ambiguous meaning for
numerical arguments: it returns the floor of the mathematical
result of division if the arguments are ints or longs, but it
returns a reasonable approximation of the division result if the
arguments are floats or complex.
See: PEP 238

Python Logarithm Function

I'm looking for an example of operations with logarithms in Python. I've tried with sympy and numpy and I still can't do what I want. For example, for an input like this:
log(x+1)+log(4-x)=log(100) # it's just an example
the output should give me the x value. I need to do this with any other functions like log(x+1)=4 or log(x)-log(x+1)=log(x).
Is there some method or somewhere (documentation or similar) where can I find how to do this?
I may be misunderstanding what you need to do because you said you tried sympy already. However, it looks like you just want to solve for x in an algebraic equation.
Solving for x in the equation
log(x+1)+log(4-x)=log(100)
using sympy would be
>>> from sympy import Symbol, solve, log
>>> x = Symbol('x')
>>> solve(log(x+1) + log(4-x) - log(100), x)
[3/2 - 5*sqrt(15)*I/2, 3/2 + 5*sqrt(15)*I/2]
If you want, you can check that these two solutions are correct with numpy.
>>> import numpy as np
>>> a = 3/2 - 5*np.sqrt(15)*1j/2
>>> b = 3/2 + 5*np.sqrt(15)*1j/2
>>> np.log(a + 1) + np.log(4-a)
(4.6051701859880918+0j)
>>> np.log(b + 1) + np.log(4-b)
(4.6051701859880918+0j)
>>> np.log(100)
4.6051701859880918
Is that not what you are looking for?
Since log is a non-linear function, you will need to use a non-linear solver like scipy.optimize.fsolve. It take in a function and a guess value and returns the answer in the form of an array. For simplicity reason, I defined the function as a lambda function since we don't need it outside of this line, but creating a function using standard def methods would work as well. The [0] on the back end get the value out of the array to return just the float.
import scipy.optimize
import math
scipy.optimize.fsolve(lambda x: math.log(x+1) - 4, 5)[0] # 5 is guess value
>>> 53.598
# Check
math.exp(4) - 1
>>> 53.598
Good advice already given. I just note that you can also check the answer in SymPy.
>>> L, R = log(x+1)+log(4-x), log(100)
>>> eq = Eq(L, R)
>>> eq
log(-x + 4) + log(x + 1) == log(100)
>>> sol = solve(eq)
>>> [eq.subs(x, i) for i in sol]
[True, True]
So in the Eq form the solutions were verified automatically. This is not always
true but you can use numerical evaluation to check the value:
>>> f = eq.lhs - eq.rhs; f
log(-x + 4) + log(x + 1) - log(100)
>>> f.subs(x, sol[0])
-log(100) + log(5/2 - 5*sqrt(15)*I/2) + log(5/2 + 5*sqrt(15)*I/2)
>>> _.n()
0.e-124 + 0.e-125*I
>>> f.subs(x, sol[0]).n(chop=True) # the small numbers can be chopped
0

Complex number in python

How to write a complex number in python? Indeed I have:
import math
a=3
b=4
function=a*j*x+b*y
I don't want to write directly 3j in my function since I absolutely want to use a, so how to convert a into a complex number? Cause in matlab it works when printing :
a=3
b=a*i
The result will gave: 0 + 3.0000i
Thank you for your answers.
j alone is a variable, you can have the complex number by typing 1j
>>> type(j)
NameError: name 'j' is not defined
>>> type(1j)
<type 'complex'>
So your code can be written as a function as
def function(x, y):
a = 3
b = 4
return a*1j*x+b*y
You can use the complex function to create a complex number from variables:
>>> a = 3
>>> b = 4
>>> complex(a, b)
(3+4j)
You can simply use Python's Built in complex() function
>>> first_number = 10
>>> second_number = 15
>>> complex(first_number, second_number)
(10+15j)

Categories