math - Haskell 和二次方程

标签 math haskell functional-programming complex-numbers quadratic

我必须编写一个程序来解决二次方程,返回一个复数结果。

到目前为止,我已经定义了一个复数,将其声明为 num 的一部分,因此 +、- 和 * - 可以发生。

我还为二次方程定义了一种数据类型,但我现在坚持二次方程的实际求解。我的数学很差,所以任何帮助将不胜感激......

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!

编辑:我似乎错过了使用我自己的复数数据类型的全部要点是了解自定义数据类型。我很清楚我可以使用 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

在实践中:
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)]

并适应使用您的术语:
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)

虽然我还没有测试过那个代码

关于math - Haskell 和二次方程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1224178/

相关文章:

haskell - 为什么 Haskell 采用一个参数

java - RxJava 与 Single.zip 中嵌套的 Single.flatMap 相同吗?

haskell - 定义自定义 "Ambigous type variable"函数时出现 "read"错误

algorithm - 对数大 O 与平方根

python - 使用 Python 创建一个单位圆计算器?

c++ - 有没有更有效的方法来计算百分比?

haskell - 使用类型来强制正确性

Ruby 数组模式匹配

scala - 如何使用日志编写清晰的代码?

c - Julia 用实数设置计算