So i'm trying to write a quadratic solver which will find results whether the coefficients are real/complex or whether the roots are real/complex. So far i've covered everything except for when the coefficients are complex. by saying the discriminant = b**2 - 4 * a * c i can account for if discriminant is >, < or == to 0. The only thing i don't know how to do is account for when the discriminant has some complex component of it (for example if a=1, b=-i and c=4). Any idea how I can add that part in? Here's what I have so far for reference:
import math
import cmath
def quadSolver(a,b,c, tol = 1e-18):
print('Equation: {0}x**2 + {1}x + {2}'.format(a,b,c))
if a==b==0:
if c!=0:
print('Has no roots')
else:
print('Has an infinite number of roots')
return
if a==0:
print('Has one root')
print(-c/b)
return
discriminant = b**2 - 4 * a * c
if isinstance(discriminant, complex):
root1 = (-b + cmath.sqrt(discriminant))/(2*a)
root2 = (-b - cmath.sqrt(discriminant))/(2*a)
print('Has two roots:')
print(root1)
print(root2)
if discriminant > 0:
root1 = (-b + math.sqrt(discriminant))/ (2 * a)
root2 = (-b - math.sqrt(discriminant))/ (2 * a)
print('Has two roots:')
print(root1)
print(root2)
elif discriminant == 0:
root1 = float(-b + math.sqrt(discriminant))/ (2 * a)
print('Has a double root:')
print(root1)
elif discriminant < 0:
root1 = (-b + cmath.sqrt(discriminant))/ (2 * a)
root2 = (-b - cmath.sqrt(discriminant))/ (2 * a)
print('Has two complex roots:')
print(root1)
print(root2)
If I understand correctly, the following if statement can handle a complex discriminant:
if isinstance(discriminant, complex):
root1 = (-b + cmath.sqrt(discriminant))/(2*a)
.
.
.
I am assuming the problem was checking for a complex discriminant, is this correct?
Edit:
Based on the comment, it sounds like you have to put this as the first "if" statement, and make the if discriminant > 0 and elif.
Related
So I wanted to create a Python program to solve a second-degree equation, which tries to find X1 and X2. Here is the code
from math import sqrt
import time
a=int(input("Put a First Number:"))
b=int(input("Put a Second Number:"))
c=int(input("Put a Third Number:"))
Delta =pow(b,2)- 4*a*c
OOF=((-1 * b) -sqrt(Delta)) / 2*a
OOF2=((-1 * b) +sqrt(Delta)) / 2*a
if Delta <= 0:
print("Delta=")
print(Delta)
time.sleep(2)
print("There is No Solution")
print("SR= Ø")
elif Delta == 0:
print("there is a double solution:")
print("-b/a:"+ -b/a)
print("S R ="+ -b/a)
else:
print("there is 2 Solution:")
print("X1=-b-squareD/2a="+ OOF)
print("X2=-b+squareD/2a="+ OOF2)
This error popped up
OOF=((-1 * b) -sqrt(Delta)) / 2*a
ValueError: math domain error
Any solutions please?
You have to move the calculation of OOF and OOF2 when you are sure the Delta isn't negative otherwise you are trying to calculate square root of a negative number.
if Delta <= 0:
print("Delta= ", Delta) #This looks better
time.sleep(2)
print("There is No Solution")
print("SR= Ø")
elif Delta == 0:
print("there is a double solution:")
print("-b/a: ", -b/a)
print("S R = ", -b/a)
else:
OOF=((-1 * b) -sqrt(Delta)) / 2*a
OOF2=((-1 * b) +sqrt(Delta)) / 2*a
print("there is 2 Solution:")
print("X1=-b-squareD/2a= ", OOF) #changed from "X1=-b-squareD/2a="+ OOF
print("X2=-b+squareD/2a= ", OOF2) #changed from "X2=-b+squareD/2a="+ OOF2
This question already has an answer here:
ValueError: math domain error - Quadratic Equation (Python)
(1 answer)
Closed 2 years ago.
So I was making a quadradic equation solver in Python and when the calculation was happening, an error came up and I'm not sure what is happening.
from math import sqrt
a = float(input("a: "))
b = float(input("b: "))
c = float(input("c: "))
Z = (b * b) - (4 * a * c)
x1 = ((-b) + float(sqrt(Z))) / (2 * a)
x2 = ((-b) - float(sqrt(Z))) / (2 * a)
print("x = " + str(x1))
print("x = " + str(x2))
This is the code.
It's probably because if (4 * a * c) > (b * b), Z becomes negative and square root of a negative number results in an imaginary number. math.sqrt() doesn't take negative parameters.
Edit: As #jakub said so, you can try getting the absolute value's square root.
I'm trying to create a quadratic equation solver but it doesn't seem to be working when I put in a coefficient greater than 1? The code and error message is below. Any help is greatly appreciated.
print "Welcome to the quadratic equation solver."
print "The general quadratic equation = ax^2 + bx + c.\n"
def POS(a,b):
#This function gives the point at which the quadratic turns
tp = float((-b)/(a*2))
return (tp)
#This allows for the user to input the values of the variables
while True:
s = raw_input ("Please insert a numerical value for a: ")
try:
a = float(s)
break
except ValueError:
print "Please enter a numeric value."
print ("Well done.\n")
while True:
s = raw_input ("Please insert a numerical value for b: ")
try:
b = float(s)
break
except ValueError:
print "Please enter a numeric value."
print ("Well done.\n")
while True:
s = raw_input ("Please insert a numerical value for c: ")
try:
c = float(s)
break
except ValueError:
print "Please enter a numeric value."
print ("Well done.\n")
#This uses the function to give the co-ordinate of the turning point
print POS(a,b), "is the x-value of the turning point"
print ((a)*(POS(a,b)**2))+((b)*POS(a,b))+c, "is they y-value of the turning point. \n"
#This tells whether the quadratic is positive or negative
if a >0:
print "The quadratic is positive.\n"
if a<0:
print "The quadratic is negative.\n"
#This determines the root of the quadratic
root1 = (-b +((b**2) - (4*a*c))**0.5) / (2 * a)
root2 = (-b -((b**2) - (4*a*c))**0.5) / (2 * a)
print "The quadratic has a root at x =",root1
if root1 != root2:
print "The quadratic has another root at x =",
#This uses the discriminant to determine the nature of the quadratic
if (b**2)-(4*a*c) == 0:
print root1
elif (b**2)-(4*a*c) > 0:
print root1 and root2
elif (b**2)-(4*a*c) < 0:
print "The quadratic contains no roots"
for x in range(-1000,1000):
quadratic = (a*x**2)+(b*x)+c
#Determines the derivitive and second derivitive of the quadratic
print "The derivitive of the quadratic is: ",2*a,"x", "+",b
print "The second derivitive of the quadratic is"
#Create plot
X = arange (-1000,1000,1)
plot(X, quadratic, linewidth=3, label="quadratic")
#Create title and axes label
title ("Graph of the quadratic")
xlabel ("x")
ylabel ("y")
#grid
grid(True)
legend()
show()
Error message:
Traceback (most recent call last):
File "C:\Users\Peter\Downloads\test.py", line 49, in <module>
root1 = (-b +((b**2) - (4*a*c))**0.5) / (2 * a)
ValueError: negative number cannot be raised to a fractional power
You can also switch to Python3 so that instead of a ValueError your number will be implicitly cast to a complex number.
(-2)**.2
(0.9293164906031477+0.6751879523998812j)
Part of your code:
#This determines the root of the quadratic
root1 = (-b +((b**2) - (4*a*c))**0.5) / (2 * a)
root2 = (-b -((b**2) - (4*a*c))**0.5) / (2 * a)
print "The quadratic has a root at x =",root1
if root1 != root2:
print "The quadratic has another root at x =",
#This uses the discriminant to determine the nature of the quadratic
if (b**2)-(4*a*c) == 0:
print root1
elif (b**2)-(4*a*c) > 0:
print root1 and root2
elif (b**2)-(4*a*c) < 0:
print "The quadratic contains no roots"
for x in range(-1000,1000):
quadratic = (a*x**2)+(b*x)+c
Let's replace (b**2)-(4*a*c) with D:
#This determines the root of the quadratic
D = (b**2)-(4*a*c)
root1 = (-b +(D)**0.5) / (2 * a)
root2 = (-b -(D)**0.5) / (2 * a)
print "The quadratic has a root at x =", root1
if root1 != root2:
print "The quadratic has another root at x =",
#This uses the discriminant to determine the nature of the quadratic
if D == 0:
print root1
elif D > 0:
# old code:
# print root1 and root2
# new code:
print root1, root2
elif D < 0:
print "The quadratic contains no roots"
for x in range(-1000,1000):
quadratic = (a*x**2)+(b*x)+c
Problem in these two lines:
root1 = (-b +(D)**0.5) / (2 * a)
root2 = (-b -(D)**0.5) / (2 * a)
If D is less than 0, this lines will raise ValueError you got. As error message said number cannot be raised to a fractional power. So we have to check if D is less than 0 or not.
#This determines the root of the quadratic
D = (b**2)-(4*a*c)
# new code:
if D >= 0:
root1 = (-b +(D)**0.5) / (2 * a)
root2 = (-b -(D)**0.5) / (2 * a)
print "The quadratic has a root at x =", root1
if root1 != root2:
print "The quadratic has another root at x =", root2
#This uses the discriminant to determine the nature of the quadratic
# We've already printed root1 and root2
# if D == 0:
# print root1
# elif D > 0:
# print root1, root2
# D < 0
else:
print "The quadratic contains no roots"
for x in range(-1000,1000):
quadratic = (a*x**2)+(b*x)+c
#This uses the discriminant to determine the nature of the quadratic
if (b**2)-(4*a*c) == 0:
print root1
elif (b**2)-(4*a*c) > 0:
print root1 and root2
elif (b**2)-(4*a*c) < 0:
print "The quadratic contains no roots"
Perform this check before you process the roots and break if it is a complex root.
>>> a=2
>>> b=4
>>> c=1
>>> delta=math.pow(b,2)-4*a*c
>>> math.sqrt(delta) #raises error for -ve integers
3.4641016151377544
gamma=math.sqrt(delta)
>>>root1=(-b+gamma)/2/a
>>>root2=(-b-gamma)/2/a
I think the problem with your code is caused due to the following part:
#This determines the root of the quadratic
root1 = (-b +((b**2) - (4*a*c))**0.5) / (2 * a)
root2 = (-b -((b**2) - (4*a*c))**0.5) / (2 * a)
print "The quadratic has a root at x =",root1
if root1 != root2:
print "The quadratic has another root at x =",
#This uses the discriminant to determine the nature of the quadratic
if (b**2)-(4*a*c) == 0:
print root1
elif (b**2)-(4*a*c) > 0:
print root1 and root2
elif (b**2)-(4*a*c) < 0:
print "The quadratic contains no roots"
Any negative number when raised to a fractional power will return a complex number which the computer is not able to calculate.
In (b**2) - (4*a*c))**0.5 there is a possibility that b**2 is less than 4*a*c. In such a case there would occur a ValueError.
To prevent this: you should structure your code in the following manner-
if (b**2)-(4*a*c) == 0:
print root1
elif (b**2)-(4*a*c) > 0:
root1 = (-b +((b**2) - (4*a*c))**0.5) / (2 * a)
root2 = (-b -((b**2) - (4*a*c))**0.5) / (2 * a)
print "The quadratic has a root at x =",root1
if root1 != root2:
print "The quadratic has another root at x =",
print root1 and root2
elif (b**2)-(4*a*c) < 0:
print "The quadratic contains no roots"
The user is supposed to put in a value for A, B, and C and get the roots of the quadratic equation. Mathematically, my code gives the wrong answer:
print "Quadratic Formula Calculator!!!"
a = input("Please, enter value for A: ")
b = input("Please, enter value for B: ")
c = input("Please, enter value for C: ")
quad =(b**2 - 4 * a * c)
if quad >= 0:
quad ** 0.5
print "quad"
else:
print "can not compute"
solution1 = (-b + quad) / (2 * a)
solution2 = (b + quad) / (2 * a)
print " Solution 1!!!:", solution1
print " Soultion 2!!!:", solution2
You need this:
quad = quad ** 0.5
Instead of just quad ** 0.5.
And solutions are:
(-b + quad) / (2 * a)
(-b - quad) / (2 * a)
And if you can not compute for negative values of discriminant (you can, the answer would be a complex conjugate values), just move calculating and printing of solution inside the quad >= 0.
Building on m0nhawk's answer, Hooked's comment (and Wikipedia) here is an approach that uses the cmath library designed for complex numbers.
from math import pow
from cmath import sqrt
print "Quadradtic Formula Calculator!!!"
print "Ax²+Bx+C=0"
print "This will attempt to solve for x"
a = input("Please, enter value for A: ")
b = input("Please, enter value for B: ")
c = input("Please, enter value for C: ")
discriminant = sqrt(pow(b,2) - (4 * a * c))
if discriminant.imag != 0:
print "discriminant is imaginary"
else:
print " Solution 1!!!:", (-b + discriminant.real) / (2 * a)
print " Solution 2!!!:", (-b - discriminant.real) / (2 * a)
cmath.sqrt will return a complex number with .imag and .real fields.
solution1 = (-b + quad) / (2 * a)
solution2 = (b + quad) / (2 * a)
This should be
solution1 = (-b + quad) / (2 * a)
solution2 = (-b - quad) / (2 * a)
The formula is -b plus or minus the root, not plus or minus b plus the root.
Since factoring a quadratic equation in my head just happens, and has done that since I learned it - how would I go about starting to write a quadratic factorer in Python?
Improving Keiths's answer:
Start with a polynomial P(x) = a*x^2 + b*x + c.
Use the quadratic formula (or another method of your choice) to find the roots r1 and r2 to P(x) = 0.
You can now factor P(x) as a*(x-r1)(x-r2).
If your factor (3x - 4)(x - 9) the solution will be 3*(x - 4/3)(x - 9).
You might want to find a way to multiply the 3 into the factors to get rid of fractions / look pretty. In this case, it might help to use fraction arithmetic instead of doubles so you can know the denominators better.
Use the quadratic formula.
I tried implementing hugomg's approach. I stole the "gcd" and "simplify fraction" function from online. Here is my sloppy approach:
from math import sqrt
def gcd(a, b):
while b:
a, b = b, a % b
return a
def simplify_fraction(numer, denom):
if denom == 0:
return "Division by 0 - result undefined"
# Remove greatest common divisor:
common_divisor = gcd(numer, denom)
(reduced_num, reduced_den) = (numer / common_divisor, denom / common_divisor)
# Note that reduced_den > 0 as documented in the gcd function.
if common_divisor == 1:
return (numer, denom)
else:
# Bunch of nonsense to make sure denominator is negative if possible
if (reduced_den > denom):
if (reduced_den * reduced_num < 0):
return(-reduced_num, -reduced_den)
else:
return (reduced_num, reduced_den)
else:
return (reduced_num, reduced_den)
def quadratic_function(a,b,c):
if (b**2-4*a*c >= 0):
x1 = (-b+sqrt(b**2-4*a*c))/(2*a)
x2 = (-b-sqrt(b**2-4*a*c))/(2*a)
# Added a "-" to these next 2 values because they would be moved to the other side of the equation
mult1 = -x1 * a
mult2 = -x2 * a
(num1,den1) = simplify_fraction(a,mult1)
(num2,den2) = simplify_fraction(a,mult2)
if ((num1 > a) or (num2 > a)):
# simplify fraction will make too large of num and denom to try to make a sqrt work
print("No factorization")
else:
# Getting ready to make the print look nice
if (den1 > 0):
sign1 = "+"
else:
sign1 = ""
if (den2 > 0):
sign2 = "+"
else:
sign2 = ""
print("({}x{}{})({}x{}{})".format(int(num1),sign1,int(den1),int(num2),sign2,int(den2)))
else:
# if the part under the sqrt is negative, you have a solution with i
print("Solutions are imaginary")
return
# This function takes in a, b, and c from the equation:
# ax^2 + bx + c
# and prints out the factorization if there is one
quadratic_function(7,27,-4)
If I run this I get the output:
(7x-1)(1x+4)