Pergunta

Eu tenho que escrever um programa para resolver equações quadráticas, retornando um resultado número complexo.

Eu recebi até agora, com a definição de um número complexo, declarando que ele seja parte de num, então +, - e * -. Ção pode ocorrer

Eu também já definiu um tipo de dados para uma equação quadrática, mas im agora preso com a resolução real do quadrática. Minha matemática é bastante pobre, por isso qualquer ajuda seria muito apreciada ...

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!

EDIT: Eu pareço ter perdido toda a ponto de usar o meu próprio número complexo tipo de dados é aprender sobre tipos de dados personalizados. Estou bem ciente de que eu poderia usar complex.data. Qualquer ajuda que poderia ser dada usando minha solução até agora seria muito apreciada. \

EDIT 2: Parece que a minha pergunta inicial foi redigido horrivelmente. Estou ciente de que a fórmula quadrática retornará ambos (ou apenas um) de raiz para mim. Onde eu estou tendo problemas está retornando essas raízes como um (complexo complexo,) tupla com o código acima.

Estou bem ciente de que eu poderia usar o construída em função quadrática como foram apresentadas abaixo, mas este não é o exercício. A idéia por trás do exercício, e aqueles que criam seu complexo tipo de dados número, é aprender sobre os tipos de dados personalizado.

Foi útil?

Solução

Como newacct disse, é apenas a equação quadrática:

(-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

na prática:

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)]

E se adaptar a usar seus termos:

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)

Embora eu não testei esse código

Outras dicas

Desde sqrt de Haskell também pode lidar com números complexos, a solução da rampion pode até mesmo ser ainda mais simplificada:

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)

Você também pode usar esta função croots com seu próprio tipo de dados, se você alterar os tipos para caber sua implementação (e chamar sua função root vez de sqrt).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top