Tho*_*mas 3 math haskell functional-programming quadratic complex-numbers
我必须编写一个程序来解决quadratics,返回一个复数的结果.
到目前为止,我已经定义了一个复数,声明它是num的一部分,所以+, - 和* - ing可以发生.
我还为二次方程定义了一种数据类型,但我现在仍然坚持二次方程式的实际求解.我的数学很差,所以任何帮助都会非常感激......
data Complex = C {
re :: Float,
im :: Float
} deriving Eq
-- Display complex numbers in the normal way
instance Show Complex where
show (C r i)
| i == 0 = show r
| r == 0 = show i++"i"
| r < 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r < 0 && i > 0 = show r ++ " + "++ show (C 0 i)
| r > 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r > 0 && i > 0 = show r ++ " + "++ show (C 0 i)
-- Define algebraic operations on complex numbers
instance Num Complex where
fromInteger n = C (fromInteger n) 0 -- tech reasons
(C a b) + (C x y) = C (a+x) (b+y)
(C a b) * (C x y) = C (a*x - b*y) (b*x + b*y)
negate (C a b) = C (-a) (-b)
instance Fractional Complex where
fromRational r = C (fromRational r) 0 -- tech reasons
recip (C a b) = C (a/((a^2)+(b^2))) (b/((a^2)+(b^2)))
root :: Complex -> Complex
root (C x y)
| y == 0 && x == 0 = C 0 0
| y == 0 && x > 0 = C (sqrt ( ( x + sqrt ( (x^2) + 0 ) ) / 2 ) ) 0
| otherwise = C (sqrt ( ( x + sqrt ( (x^2) + (y^2) ) ) / 2 ) ) ((y/(2*(sqrt ( ( x + sqrt ( (x^2) + (y^2) ) ) / 2 ) ) ) ) )
-- quadratic polynomial : a.x^2 + b.x + c
data Quad = Q {
aCoeff, bCoeff, cCoeff :: Complex
} deriving Eq
instance Show Quad where
show (Q a b c) = show a ++ "x^2 + " ++ show b ++ "x + " ++ show c
solve :: Quad -> (Complex, Complex)
solve (Q a b c) = STUCK!
Run Code Online (Sandbox Code Playgroud)
编辑:我似乎错过了使用我自己的复数数据类型的全部观点是了解自定义数据类型.我很清楚我可以使用complex.data.到目前为止,使用我的解决方案可以提供的任何帮助将不胜感激.
编辑2:似乎我最初的问题措辞可怕.我知道二次公式会将两个(或只是一个)根返回给我.我遇到麻烦的地方是将这些根作为一个(复杂的,复杂的)元组返回上面的代码.
我很清楚我可以使用内置的二次函数,如下所示,但这不是练习.练习背后的想法,以及创建自己的复数数据类型,是要了解自定义数据类型.
就像newacct所说,它只是二次方程式:
(-b +- sqrt(b^2 - 4ac)) / 2a
module QuadraticSolver where
import Data.Complex
data Quadratic a = Quadratic a a a deriving (Show, Eq)
roots :: (RealFloat a) => Quadratic a -> [ Complex a ]
roots (Quadratic a b c) =
if discriminant == 0
then [ numer / denom ]
else [ (numer + root_discriminant) / denom,
(numer - root_discriminant) / denom ]
where discriminant = (b*b - 4*a*c)
root_discriminant = if (discriminant < 0)
then 0 :+ (sqrt $ -discriminant)
else (sqrt discriminant) :+ 0
denom = 2*a :+ 0
numer = (negate b) :+ 0
Run Code Online (Sandbox Code Playgroud)
在实践中:
ghci> :l QuadraticSolver
Ok, modules loaded: QuadraticSolver.
ghci> roots (Quadratic 1 2 1)
[(-1.0) :+ 0.0]
ghci> roots (Quadratic 1 0 1)
[0.0 :+ 1.0,(-0.0) :+ (-1.0)]
Run Code Online (Sandbox Code Playgroud)
并适应使用您的条款:
solve :: Quad -> (Complex, Complex)
solve (Q a b c) = ( sol (+), sol (-) )
where sol op = (op (negate b) $ root $ b*b - 4*a*c) / (2 * a)
Run Code Online (Sandbox Code Playgroud)
虽然我没有测试过那段代码
由于Haskell sqrt还可以处理复数,因此可以进一步简化rampion的解决方案:
import Data.Complex
-- roots for quadratic equations with complex coefficients
croots :: (RealFloat a) =>
(Complex a) -> (Complex a) -> (Complex a) -> [Complex a]
croots a b c
| disc == 0 = [solution (+)]
| otherwise = [solution (+), solution (-)]
where disc = b*b - 4*a*c
solution plmi = plmi (-b) (sqrt disc) / (2*a)
-- roots for quadratic equations with real coefficients
roots :: (RealFloat a) => a -> a -> a -> [Complex a]
roots a b c = croots (a :+ 0) (b :+ 0) (c :+ 0)
Run Code Online (Sandbox Code Playgroud)
croots如果您更改类型以适合您的实现(并调用您的root函数而不是sqrt),您也可以将此函数与您自己的数据类型一起使用.