Pregunta

Tengo que escribir un programa para resolver cuadráticos, devolviendo un resultado de número complejo.

Llegué hasta ahora, con la definición de un número complejo, declarándolo parte de num, por lo que +, - y * - ing pueden tener lugar.

También he definido un tipo de datos para una ecuación cuadrática, pero ahora estoy atascado con la resolución real de la ecuación cuadrática. Mis matemáticas son bastante pobres, por lo que cualquier ayuda sería muy 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!

EDITAR: Parece que me he perdido el punto de usar mi propio tipo de datos de números complejos es aprender sobre los tipos de datos personalizados. Soy consciente de que podría usar complex.data. Cualquier ayuda que se pueda dar usando la solución my hasta ahora sería muy apreciada. \

EDIT 2: Parece que mi pregunta inicial fue redactada horriblemente. Soy consciente de que la fórmula cuadrática me devolverá ambas (o solo la raíz). Donde tengo problemas es devolver estas raíces como una tupla (compleja, compleja) con el código anterior.

Soy muy consciente de que podría usar las funciones cuadráticas integradas que se muestran a continuación, pero este no es el ejercicio. La idea detrás del ejercicio, y de crear los propios tipos de datos de números complejos, es aprender sobre los tipos de datos personalizados.

¿Fue útil?

Solución

Como dijo newacct, es solo la ecuación cuadrá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

en la práctica:

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

Y adaptarse para usar sus términos:

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)

Aunque no he probado ese código

Otros consejos

Dado que el sqrt de Haskell también puede manejar números complejos, la solución de rampion puede incluso simplificarse aún más:

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)

También puede usar esta función croots con su propio tipo de datos, si cambia los tipos para que se ajusten a su implementación (y llame a su función root en lugar de sqrt ).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top