I'm writing a programme that converts complex numbers.
Right now I'm having problems with this piece of code:
import numpy
complexnr = 1+1j
mod= numpy.absolute(complexnr)
print(mod)
The output of this code is:
1.4142135623730951
I would like to get √2 as the output.
I have been advised to use the sympy module but I have had no luck with this either. What would be the easiest way to get this result?
EDIT
input_list = ["Enter your complex number (a+bi): ", \
"Degrees or radians?", \
"To how many decimal places do you want to round the argument?"]
output = multenterbox(text, title, input_list)
algebraline = output[0]
choice = output[1]
round2 = int(output[2])
#converting complex number to a suitable form for numpy
if "i" in algebraline:
j = algebraline.replace("i","j")
indeks = algebraline.index("i")
list = []
for element in algebraline:
list.append(element)
if "i" in algebraline and algebraline[indeks-1]=="+" or algebraline[indeks-1]=="-":
list.insert(indeks, 1)
x = "".join(str(e) for e in list)
j = x.replace("i","j")
arv = eval(j)
elif "i" not in algebraline:
arv = eval(algebraline)
#let's find the module
a = int(list[0])
b = int(list[2])
module = sqrt(a**2+b**2)
this method works well when the complex number is 1+i for example, however when i try to insert sqrt(3)-1i, the list looks like this ['s', 'q', 'r', 't', '(', '3', ')', '-', 1, 'i'] and my programme won't work. Same problem occurs when b is a root (for example 1-sqrt(3)i). What can be done to make it work for square roots as well? (I need numpy later on to calculate angles, that's why converting 'i' into 'j' is important)
Works by using
I (from sympy) rather than 1j
builtin abs function which calls sympby.Abs for complex arguments
Code
from sympy import I
complexnr = 1 + I # use I rather than 1j
display(abs(complexnr)) # also works with np.abs and np.absolute
Output:
print(abs(complexnr))
Output: sqrt(2)
If you want to use SymPy, you have to write the complex numbers as sympy expressions.
from sympy import *
cabs = lambda z: sqrt(re(z)**2 + im(z)**2)
complexnr = 1 + 1j
print(cabs(complexnr))
# out: 1.4142135623731
We are getting a float number because complexnr is of type complex and its real and imaginary parts are of type float. Thus, SymPy's re and im functions returns float numbers. But when sqrt receives a float number, it evaluates the result.
We can workaround this problem in two ways.
The first: if we are dealing with simple complex numbers where real and imaginary parts are integers, we can write the complex number as a string, sympify it (which means convert to a sympy expression):
complexnr = sympify("1 + 1j")
print(cabs(complexnr))
# out: sqrt(2)
A second way consist in using the complex number directly, then apply nsimplify in order to attempt to convert the resulting float number to some symbolic form:
complexnr = 1 + 1j
result = cabs(complexnr) # result is a Float number, 1.4142135623731
print(result.nsimplify())
# out: sqrt(2)
Related
I have four numbers a, b, c, d (in the source code below). And I want to get the arithmetic combination(formula) of the these numbers that gives me another number x, say:
x=12.9154769165485450430573664439479027694158016708245349917377671920719960957195046694035973.
I have searched online and got the code below, but am not getting any formula as output.
from itertools import permutations
a=1.5931220318142209081847200718800513284478983895232845771598115094865772293425176551147041
b=1.4180958678849065567601929430299366804279726526182465238391256914846175095759022850508064
c=2.6859936848766770740741701602124664887178336154356167143236626569580529789903079049227949
d=3.3917959415836179238295055450635509297663016085355811568226926449910165645921925937776673
x=12.9154769165485450430573664439479027694158016708245349917377671920719960957195046694035973
numbers = ["a","b","c","d"]
target = x
operators = ["+","-","*","/"]
for values in permutations(numbers,len(numbers)):
for oper in permutations(operators,len(numbers)-1):
formula = "".join(o+v for o,v in zip([""]+list(oper),values))
if eval(formula) == target: print(formula,"=",target)
I will greatly appreciate any help to get this done.
Thank you
I would recommend switching to something like the below:
(1) you do permutation on the operators, which means you always use ALL of them. With this numbers you will never even get close to equality using ALL arithmetic operators. I replaced it with combinations with replacement (i.e. combination allowing duplicates).
(2) IF you want to operate on floats - I would aim not for equality, but e.g. assume 0.01 error, otherwise you might run into issues not coming from maths, but from how floats are represented in python.
from itertools import permutations, combinations_with_replacement
a=1.5931220318142209081847200718800513284478983895232845771598115094865772293425176551147041
b=1.4180958678849065567601929430299366804279726526182465238391256914846175095759022850508064
c=2.6859936848766770740741701602124664887178336154356167143236626569580529789903079049227949
d=3.3917959415836179238295055450635509297663016085355811568226926449910165645921925937776673
x=12.9154769165485450430573664439479027694158016708245349917377671920719960957195046694035973
numbers = ["a","b","c","d"]
target = x
operators = ["+","-","*","/"]
for values in permutations(numbers,len(numbers)):
for oper in combinations_with_replacement(operators,len(numbers)-1):
formula = "".join(o+v for o,v in zip([""]+list(oper),values))
if abs(eval(formula) - target)<0.01: print(formula,"=",target)
It looks like there is no combination of these four numbers that equals x.
Floating point operations have round-off error. The code you have checks if any operations will equal x exactly, but that is highly unlikely. Instead, you should be checking if the difference is within some value of x. I changed the code to the following:
from itertools import permutations
a = 1.5931220318142209081847200718800513284478983895232845771598115094865772293425176551147041
b = 1.4180958678849065567601929430299366804279726526182465238391256914846175095759022850508064
c = 2.6859936848766770740741701602124664887178336154356167143236626569580529789903079049227949
d = 3.3917959415836179238295055450635509297663016085355811568226926449910165645921925937776673
x = 12.9154769165485450430573664439479027694158016708245349917377671920719960957195046694035973
EPSILON = 1
numbers = ["a", "b", "c", "d"]
target = x
operators = ["+", "-", "*", "/"]
for values in permutations(numbers, len(numbers)):
for oper in permutations(operators, len(numbers) - 1):
formula = "".join(o + v for o, v in zip([""] + list(oper), values))
actual = eval(formula)
if abs(actual - target) < EPSILON:
print(formula, "=", actual)
And there is no combination that evaluates to within 1 of the target.
When running this code it is giving me this error:
x = p((1/2) - (2/q)) TypeError: 'int' object is not callable
p = 0
q = 0
while (p==0):
p = int(input("Enter an integer for p: "))
while (q==0):
q = int(input("Enter an integer for q: "))
x = p((1/2) - (2/q))
print(x)
You didn't use *, the multiplication operator:
x = p * ((1/2) - (2/q))
------^ here
In math equations, the multiplication operator is often left out. E.g. a(b-2) means "a times the quantity b-2).
In programming however, you must explicitly include the multiplication operator. E.g. a*(b-2).
In Python (and most other languages), when a token is followed by open/close parenthesis, it implies that a function is being called. This is why you received the 'int' object is not callable error; because p is an int, and it looked like you were trying to call it.
You have another problem in your translation from "equation" to Python. In Python 2, integer division is used (when both operands are integers, of course). Which means that this term:
x = p * ((1/2) - (2/q))
^^^^^
is going to equal zero.
In Python 3, this is not the case. Division (with a single /) is always floating point.
Since this is probably not desired, you should do one of the following:
Convert one of the terms to float, e.g. float(1)/2
from __future__ import division which enables the Python 3 behavior
Just replace the term with 0.5
Because you are trying to do something like this:
p()
but p is variable.
Given a value numerical value x, you can just do this float(x).is_integer() to check if it's an integer. Is there a way to do this for complex numbers?
I'm trying to use list comprehension to take only the integer roots of a polynomial over a finite field which are integers.
[r for r in solve(f,domain=FiniteField(p)) if float(r).is_integer()]
but if the solve function returns complex roots, this doesn't work.
Does anyone know how to either: check if a given (possibly complex number) is an integer OR know if there's a SymPy function to get the roots of a polynomial over a finite field which are integers?
Use the ground_roots function along with the modulus keyword argument. This returns the roots modulo p, with multiplicities. Here's an example:
>>> from sympy import Symbol, ground_roots
>>> x = Symbol('x')
>>> f = x**5 + 7*x + 1
>>> p = 13
>>> ground_roots(f, modulus=p)
{-5: 1, 4: 2}
That says that the roots of poly modulo 13 are -5 and 4, with the root 4 having multiplicity 2.
By the way, it looks to me as though complex numbers are a red herring here: the roots of an integral polynomial over a finite field can't naturally be regarded as complex numbers. The call to solve in your original post is ignoring the domain argument and is simply giving algebraic numbers (which can reasonably be interpreted as complex numbers) as its results, which is probably why you ended up looking at complex numbers. But these aren't going to help when trying to find the roots modulo a prime p.
float.is_integer(z.real) tells you if the real part is integer
If you want to check if imaginary part is zero, you can do this:
In [17]: a=2 + 2j
In [18]: bool(a.imag)
Out[18]: True
In [19]: b=2 + 0j
In [20]: bool(b.imag)
Out[20]: False
Using a list comprehension as in your original question, one could do:
roots = [complex(r) for r in solve(f, domain=FiniteField(p))]
int_roots = [z.real for z in roots if z.real.is_integer() and not z.imag]
I need to convert a binary input into a decimal integer. I know how to go from a decimal to a binary:
n = int(raw_input('enter a number: '))
print '{0:b}'.format(n)
I need to go in the reverse direction. My professor said that when he checks our code, he is going to input 11001, and he should get 25 back. I've looked through our notes, and I cannot figure out how to do this. Google and other internet resources haven't been much help either.
The biggest problem is that we are not allowed to use built-in functions. I understand why we are not allowed to use them, but it's making this problem much more difficult, since I know Python has a built-in function for binary to decimal.
You can use int and set the base to 2 (for binary):
>>> binary = raw_input('enter a number: ')
enter a number: 11001
>>> int(binary, 2)
25
>>>
However, if you cannot use int like that, then you could always do this:
binary = raw_input('enter a number: ')
decimal = 0
for digit in binary:
decimal = decimal*2 + int(digit)
print decimal
Below is a demonstration:
>>> binary = raw_input('enter a number: ')
enter a number: 11001
>>> decimal = 0
>>> for digit in binary:
... decimal = decimal*2 + int(digit)
...
>>> print decimal
25
>>>
Binary to Decimal
int(binaryString, 2)
Decimal to Binary
format(decimal ,"b")
There is actually a much faster alternative to convert binary numbers to decimal, based on artificial intelligence (linear regression) model:
Train an AI algorithm to convert 32-binary number to decimal based.
Predict a decimal representation from 32-binary.
See example and time comparison below:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import numpy as np
y = np.random.randint(0, 2**32, size=10_000)
def gen_x(y):
_x = bin(y)[2:]
n = 32 - len(_x)
return [int(sym) for sym in '0'*n + _x]
X = np.array([gen_x(x) for x in y])
model = LinearRegression()
model.fit(X, y)
def convert_bin_to_dec_ai(array):
return model.predict(array)
y_pred = convert_bin_to_dec_ai(X)
Time comparison:
This AI solution converts numbers almost x10 times faster than conventional way!
If you want/need to do it without int:
sum(int(c) * (2 ** i) for i, c in enumerate(s[::-1]))
This reverses the string (s[::-1]), gets each character c and its index i (for i, c in enumerate(), multiplies the integer of the character (int(c)) by two to the power of the index (2 ** i) then adds them all together (sum()).
I started working on this problem a long time ago, trying to write my own binary to decimal converter function. I don't actually know how to convert decimal to binary though! I just revisited it today and figured it out and this is what I came up with. I'm not sure if this is what you need, but here it is:
def __degree(number):
power = 1
while number % (10**power) != number:
power += 1
return power
def __getDigits(number):
digits = []
degree = __degree(number)
for x in range(0, degree):
digits.append(int(((number % (10**(degree-x))) - (number % (10**(degree-x-1)))) / (10**(degree-x-1))))
return digits
def binaryToDecimal(number):
list = __getDigits(number)
decimalValue = 0
for x in range(0, len(list)):
if (list[x] is 1):
decimalValue += 2**(len(list) - x - 1)
return decimalValue
Again, I'm still learning Python just on my own, hopefully this helps. The first function determines how many digits there are, the second function actually figures out they are and returns them in a list, and the third function is the only one you actually need to call, and it calculates the decimal value. If your teacher actually wanted you to write your own converter, this works, I haven't tested it with every number, but it seems to work perfectly! I'm sure you'll all find the bugs for me! So anyway, I just called it like:
binaryNum = int(input("Enter a binary number: "))
print(binaryToDecimal(binaryNum))
This prints out the correct result. Cheers!
The input may be string or integer.
num = 1000 #or num = '1000'
sum(map(lambda x: x[1]*(2**x[0]), enumerate(map(int, str(num))[::-1])))
# 8
a = input('Enter a binary number : ')
ar = [int(i) for i in a]
ar = ar[::-1]
res = []
for i in range(len(ar)):
res.append(ar[i]*(2**i))
sum_res = sum(res)
print('Decimal Number is : ',sum_res)
Using the power (**) function is a bit of a waste, so #user2555451's solution really is the way to go (Horner's method). Here's a fancy variation on it (less efficient, though, since the string needs to be reversed. The str-cast is there to allow for integers to be passed as well):
from itertools import accumulate, repeat
from operator import mul
def bin2dec(bin_str):
return sum(
int(n) * m for n, m in zip(
str(bin_str)[::-1],
accumulate((repeat(2)), func=mul, initial=1)))
I have an expression from a sympy calculation:
sqrt(pi)*(0.333333333333333*a + 0.333333333333333*b - 2.66666666666667*c**2)
where a,b,c are symbols, and would like to parse it so that the floats are replaced with rationals like in
sqrt(pi)*(1/3*a + 1/3*b - 8/3*c**2)
I know how to do one by hand,
In[24] Rational(str(0.333333333333333)).limit_denominator(1000)
Out[24]: 1/3
but do not quite know how to go about parsing the atoms and picking only the ones that are floats, and substituting back the rational number approximation.
What is the smartest way of doing these substitutions in the expression?
Use nsimplify:
>>> print(nsimplify(sqrt(pi)*(0.333333333333333*a + 0.333333333333333*b - 2.66666666666667*c**2)))
sqrt(pi)*(a/3 + b/3 - 8*c**2/3)
After a bit of fiddling, I think I have found a way to do it, but I am not sure that it will cover all the corner cases. At any rate here it is. Any suggestions for improvement?
import sympy
def rationalize_coeffs(expr):
for i in expr.atoms(sympy.Float):
r = sympy.Rational(str(i)).limit_denominator(1000)
expr = expr.subs(i, r)
return expr
if __name__=='__main__':
# given a sympy expression expr
x,y,z = sympy.symbols('x y z')
# expr_orig = 2/57.*x + 3./4.*y + 3./4.*z
expr = 0.0350877192982456*x + 0.75*y + 0.75*z
print rationalize_coeffs(expr)