Question

Je dois écrire un programme pour résoudre les problèmes de quadrature, renvoyant un résultat de nombre complexe.

J’ai eu jusqu’à présent à définir un nombre complexe, en déclarant qu’il faisait partie de num, afin que +, - et * - puissent avoir lieu.

J'ai également défini un type de données pour une équation du second degré, mais je suis maintenant bloqué dans la résolution du problème du second degré. Mes calculs sont plutôt médiocres, toute aide serait donc grandement appréciée ...

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: Il semble que je n’aie pas compris l’intérêt d’utiliser mon propre type de données à nombre complexe est d’en savoir plus sur les types de données personnalisés. Je suis bien conscient que je pourrais utiliser complex.data. Toute aide pouvant être apportée à l'aide de ma solution à ce jour serait grandement appréciée. \

MODIFIER 2: Il semble que ma question initiale ait été formulée de manière horrible. Je suis conscient que la formule quadratique me rendra les deux (ou la seule) racine. J'ai du mal à renvoyer ces racines sous forme de tuple (complexe) avec le code ci-dessus.

Je sais bien que je pourrais utiliser les fonctions quadratiques intégrées telles qu'elles ont été affichées ci-dessous, mais ce n'est pas l'exercice. L’idée derrière l’exercice et la création de son propre type de données de nombre complexe est d’apprendre sur les types de données personnalisés.

Était-ce utile?

La solution

Comme dit newacct, il n’ya que l’équation du second degré:

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

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

Et en vous adaptant pour utiliser vos termes:

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)

Bien que je n'ai pas testé ce code

Autres conseils

Etant donné que le sqrt de Haskell peut également gérer des nombres complexes, la solution de rampion peut encore être simplifiée:

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)

Vous pouvez également utiliser cette fonction croots avec votre propre type de données, si vous modifiez les types pour les adapter à votre implémentation (et appelez votre fonction root au lieu de sqrt ).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top