Pergunta

Então eu terminar de criar o meu próprio complexo tipo de dados número em Haskell.

Eu tenho também, graças a uma outra pergunta aqui, tenho uma função que vai resolver uma equação quadrática.

O único problema agora é que o código gera um erro de análise em abraços, ao tentar resolver um quadrático com raízes complexas.

i. Em abraços ...

Main> solve (Q 1 2 1)
(-1.0,-1.0)

Main> solve (Q 1 2 0)
(0.0,-2.0)

Main> solve (Q 1 2 2)
(
Program error: pattern match failure: v1618_v1655 (C -1.#IND -1.#IND)

Parece que o meu como o seu problema uma após a raiz quadrada tem sido aplicado, mas eu não tenho certeza. Qualquer ajuda tentando pegar o que está errado ou quaisquer indicações quanto ao que isso significa erro seria brilhante.

Obrigado,

Thomas

O Código:

-- A complex number z = (re +im.i) is represented as a pair of Floats

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) = ( sol (+), sol (-) )
  where sol op = (op (negate b) $ root $ b*b - 4*a*c) / (2 * a)
Foi útil?

Solução

Seus números parecem denormalized em sua erro:

(C -1.#IND -1.#IND)

Neste caso, você não pode assumir que qualquer comparação no flutuador são válidos mais. Este é na definição de números de ponto flutuante. Em seguida, a sua definição de programa

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)

oportunidade licença para uma falha de padrão, porque de números desnormalizados. Você pode adicionar a seguinte condição

    | otherwise = show r ++ "i" ++ show i"

Agora, para o por que é assim, quando você avaliar

b * b - 4 * a * c

com Q 1 2 2, obtém -4, e depois na raiz, você cair no seu último caso, e na segunda equação:

              y
-----------------------------
            ________________
           /        _______
          /        / 2    2
         /   x + \/ x  + y
 2 * \  /   ----------------
      \/           2

-4 + sqrt( (-4) ^2) == 0, a partir daí, você está condenado, divisão por 0, seguido por um "NaN" (não um número), enroscando tudo

Outras dicas

Dave bateu o prego na cabeça.

Com o código original em GHCi, eu recebo:

*Main> solve (Q 1 2 2)
(*** Exception: c.hs:(11,4)-(17,63): Non-exhaustive patterns in function show

Se atualizarmos o bloco show:

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)
        | otherwise             = "???(" ++ show r ++ " " ++ show i ++ ")"

então obter essa informação em GHCi:

*Main> :l c.hs
[1 of 1] Compiling Main             ( c.hs, interpreted )

c.hs:22:0:
    Warning: No explicit method nor default method for `abs'
    In the instance declaration for `Num Complex'

c.hs:22:0:
    Warning: No explicit method nor default method for `signum'
    In the instance declaration for `Num Complex'
Ok, modules loaded: Main.
*Main> solve (Q 1 2 2)
(???(NaN NaN),???(NaN NaN))

Eu "nasceu e cresceu" na GHCi, então eu não sei exatamente como Hugs compara em verbosidade de avisos e erros; mas parece que GHCi é um vencedor claro em dizer o que deu errado.

Em cima da minha cabeça: Poderia ser um problema com a sua definição de show para Complex.

Eu noto que você não tem caso padrão como este:

 | otherwise = ...

Portanto, se suas condições com r e i são não exaustiva você vai ter um pattern match failure.

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