Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Tievoli Bruno tievolib@gmail.com
- -- Riso Santiago santiagoriso@gmail.com
- -- Gozzi Juan juanfragozzi@gmail.com
- type Complejo = (Float,Float)
- -- 1.1
- re :: Complejo -> Float
- re (a,b) = a
- -- 1.2
- im :: Complejo -> Float
- im (a,b) = b
- -- 1.3
- suma :: Complejo -> Complejo -> Complejo
- suma (a,b) (c,d) = (a+c,b+d)
- -- 1.4
- producto :: Complejo -> Complejo -> Complejo
- producto (a,b) (c,d) = (a*c-b*d,a*d+b*c)
- -- 1.5
- conjugado :: Complejo -> Complejo
- conjugado (a,b) = (a,-b)
- -- 1.6
- inverso :: Complejo -> Complejo
- inverso (a,b) = (a/(a^2+b^2),-b/(a^2+b^2))
- -- 1.7
- cociente :: Complejo -> Complejo -> Complejo
- cociente z w = producto z (inverso w)
- -- Usamos el inverso del segundo complejo para hacer la división.
- -- 1.8
- potencia :: Complejo -> Integer -> Complejo
- potencia _ 0 = (1,0)
- potencia z 1 = z
- potencia z (-1) = inverso z
- potencia z n | n > 1 = producto z (potencia z (n-1))
- | n < (-1) = producto (inverso z) (potencia z (n+1))
- -- Contemplamos tanto potencias positivas como negativas, invirtiendo el z cuando la potencia es negativa
- -- Definimos los dos límites de mi recursión, que son -1 y 1, dependiendo de que signo lleve la potencia
- -- También definimos el caso z⁰, que da siempre 1, que en coordenadas es (1,0)
- -- 1.9
- raicesCuadratica :: Float -> Float -> Float -> (Complejo,Complejo)
- raicesCuadratica a b c | delta >= 0 = (((-b+sqrt(delta))/(2*a),0),((-b-sqrt(delta))/(2*a),0))
- | otherwise = (((-b/(2*a)), sqrt(abs delta)/(2*a)), ((-b/(2*a)),-sqrt(abs delta)/(2*a)))
- where delta = b^2-4*a*c
- -- Si el discriminante es positivo, las raíces son reales.
- -- Si el discriminante es negativo, las raíces son complejas.
- -- Usamos el valor absoluto de delta, ya que la raíz cuadrada de un numero negativo, es la raíz cuadrada del valor absoluto de ese numero multiplicado por la raíz de -1, es decir, i o -i.
- -- Encontramos las raíces usando la formula resolvente.
- -- 2.1
- modulo :: Complejo -> Float
- modulo (a,b) = sqrt(a^2+b^2)
- -- 2.2
- distancia :: Complejo -> Complejo -> Float
- distancia (a,b) (c,d) = sqrt((a-c)^2+(b-d)^2)
- -- 2.3
- argumento :: Complejo -> Float
- argumento (0,0) = 0
- argumento (a,b) | a > 0 && b >= 0 = atan(b/a)
- | a > 0 && b < 0 = atan(abs b/a) + 3*pi/2
- | a < 0 = atan(b/a) + pi
- | a == 0 && b > 0 = pi/2
- | a == 0 && b < 0 = 3*pi/2
- -- En los primeros dos casos, para el mejor entendimiento, elegimos buscar el ángulo en el cuadrante 1 y luego sumarle el ángulo que le corresponde al cuadrante en el que se encuentra.
- -- Si a < 0, el caso b > 0 y b < 0 son el mismo ángulo con distinto signo, por que el arctan es simétrico en el eje x. Entonces sumarle pi nos da el ángulo correcto.
- -- (Y si b = 0, atan(b/a) = 0 + pi, que es correcto.)
- -- En los casos que quedan, son los que se encuentran sobre el eje y. No podemos usar el arctan porque no se puede dividir por 0.
- -- El primer caso es más para cubrir un edge case, pero realmente (0,0) no tiene ángulo.
- -- 2.4
- pasarACartesianas :: Float -> Float -> Complejo
- pasarACartesianas r t = (r*cos(t),r*sin(t))
- -- 2.5
- raizCuadrada :: Complejo -> (Complejo,Complejo)
- raizCuadrada z = (pasarACartesianas (sqrt(modulo z)) (argumento z/2), pasarACartesianas (sqrt(modulo z)) ((argumento z)/2 + pi))
- -- Buscamos w² = z. Definimos |z| = r, |w| = r', arg(z) = φ, arg(w) = Θ
- -- Usamos la forma trigonometrica. r'² = r => r' = sqrt(r)
- -- Para calcular el ángulo, por Moivre sabemos que 2*Θ = φ => Θ = φ/2
- -- a eso le sumamos 2kpi/2 (= k*pi), pero como la raíz es cuadrada las posibles k son 0 y 1, por lo que solo sumamos pi. (El resto de k > 1 hacen que Θ > 2pi)
- -- 2.6
- raicesCuadraticaCompleja :: Complejo -> Complejo -> Complejo -> (Complejo,Complejo)
- raicesCuadraticaCompleja a b c = (producto (suma (productoEscalar b (-1)) r1) (inverso (productoEscalar a 2)), producto (suma (productoEscalar b (-1)) r2) (inverso (productoEscalar a 2)))
- where (r1, r2) = raizCuadrada (suma (potencia b 2) (productoEscalar (producto a c) (-4)))
- -- Usamos la formula resolvente, con los dos discriminantes usando la función de arriba, que definimos como r1 y r2.
- -- 3.1
- raicesNEsimas :: Integer -> [Complejo]
- raicesNEsimas n = [ ( cos(t*(fromIntegral k)), sin(t*(fromIntegral k)) ) | k <- [0..n-1] ]
- where t = 2*pi/(fromIntegral n)
- -- Devolvemos la lista de raices de la unidad para todo k entre 0 y n-1
- -- Usamos fromIntegral para convertir el Integer en Float, sino haskell tira error de tipado
- -- 3.2
- sonRaicesNEsimas :: Integer -> [Complejo] -> Float -> Bool
- sonRaicesNEsimas n [] e = True
- sonRaicesNEsimas n arr e = modulo (suma (potencia (head arr) n) (-1,0)) < e && sonRaicesNEsimas n (tail arr) e
- -- Buscamos recursivamente que la resta entre cada elemento elevado a n de la lista y 1 sea menor a e, con e siendo normalmente un número muy chico.
- -- Si la lista se vacía, significa que todos los elementos cumplieron con la condición, es decir que son raices de la unidad.
- --Auxilirares
- productoEscalar :: Complejo -> Float -> Complejo
- productoEscalar (a,b) c = (a*c,b*c)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement