Advertisement
tievo

TP2.hs

Nov 2nd, 2022 (edited)
977
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Tievoli Bruno tievolib@gmail.com
  2. -- Riso Santiago santiagoriso@gmail.com
  3. -- Gozzi Juan juanfragozzi@gmail.com
  4.  
  5. type Complejo = (Float,Float)
  6.  
  7. -- 1.1
  8. re :: Complejo -> Float
  9. re (a,b) = a
  10.  
  11. -- 1.2
  12. im :: Complejo -> Float
  13. im (a,b) = b
  14.  
  15. -- 1.3
  16. suma :: Complejo -> Complejo -> Complejo
  17. suma (a,b) (c,d) = (a+c,b+d)
  18.  
  19. -- 1.4
  20. producto :: Complejo -> Complejo -> Complejo
  21. producto (a,b) (c,d) = (a*c-b*d,a*d+b*c)
  22.  
  23. -- 1.5
  24. conjugado :: Complejo -> Complejo
  25. conjugado (a,b) = (a,-b)
  26.  
  27. -- 1.6
  28. inverso :: Complejo -> Complejo
  29. inverso (a,b) = (a/(a^2+b^2),-b/(a^2+b^2))
  30.  
  31. -- 1.7
  32. cociente :: Complejo -> Complejo -> Complejo
  33. cociente z w = producto z (inverso w)
  34. -- Usamos el inverso del segundo complejo para hacer la división.
  35.  
  36. -- 1.8
  37. potencia :: Complejo -> Integer -> Complejo
  38. potencia _ 0 = (1,0)
  39. potencia z 1 = z
  40. potencia z (-1) = inverso z
  41. potencia z n | n > 1 = producto z (potencia z (n-1))
  42.              | n < (-1) = producto (inverso z) (potencia z (n+1))
  43.  
  44. -- Contemplamos tanto potencias positivas como negativas, invirtiendo el z cuando la potencia es negativa
  45. -- Definimos los dos límites de mi recursión, que son -1 y 1, dependiendo de que signo lleve la potencia
  46. -- También definimos el caso z⁰, que da siempre 1, que en coordenadas es (1,0)
  47.  
  48. -- 1.9
  49. raicesCuadratica :: Float -> Float -> Float -> (Complejo,Complejo)
  50. raicesCuadratica a b c | delta >= 0 = (((-b+sqrt(delta))/(2*a),0),((-b-sqrt(delta))/(2*a),0))
  51.                        | otherwise = (((-b/(2*a)), sqrt(abs delta)/(2*a)), ((-b/(2*a)),-sqrt(abs delta)/(2*a)))
  52.                        where delta = b^2-4*a*c
  53. -- Si el discriminante es positivo, las raíces son reales.
  54. -- Si el discriminante es negativo, las raíces son complejas.
  55. -- 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.
  56. -- Encontramos las raíces usando la formula resolvente.
  57.  
  58. -- 2.1
  59. modulo :: Complejo -> Float
  60. modulo (a,b) = sqrt(a^2+b^2)
  61.  
  62. -- 2.2
  63. distancia :: Complejo -> Complejo -> Float
  64. distancia (a,b) (c,d) = sqrt((a-c)^2+(b-d)^2)
  65.  
  66. -- 2.3
  67. argumento :: Complejo -> Float
  68. argumento (0,0) = 0
  69. argumento (a,b) | a > 0 && b >= 0 = atan(b/a)
  70.                 | a > 0 && b < 0 = atan(abs b/a) + 3*pi/2
  71.                 | a < 0 = atan(b/a) + pi
  72.                 | a == 0 && b > 0 = pi/2
  73.                 | a == 0 && b < 0 = 3*pi/2
  74. -- 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.
  75. -- 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.
  76. -- (Y si b = 0, atan(b/a) = 0 + pi, que es correcto.)
  77. -- 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.
  78. -- El primer caso es más para cubrir un edge case, pero realmente (0,0) no tiene ángulo.
  79.  
  80. -- 2.4
  81. pasarACartesianas :: Float -> Float -> Complejo
  82. pasarACartesianas r t = (r*cos(t),r*sin(t))
  83.  
  84. -- 2.5
  85. raizCuadrada :: Complejo -> (Complejo,Complejo)
  86. raizCuadrada z = (pasarACartesianas (sqrt(modulo z)) (argumento z/2), pasarACartesianas (sqrt(modulo z)) ((argumento z)/2 + pi))
  87. -- Buscamos w² = z. Definimos |z| = r, |w| = r', arg(z) = φ, arg(w) = Θ
  88. -- Usamos la forma trigonometrica. r'² = r => r' = sqrt(r)
  89. -- Para calcular el ángulo, por Moivre sabemos que 2*Θ = φ => Θ = φ/2
  90. -- 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)
  91.  
  92. -- 2.6
  93. raicesCuadraticaCompleja :: Complejo -> Complejo -> Complejo -> (Complejo,Complejo)
  94. raicesCuadraticaCompleja a b c = (producto (suma (productoEscalar b (-1)) r1) (inverso (productoEscalar a 2)), producto (suma (productoEscalar b (-1)) r2) (inverso (productoEscalar a 2)))
  95.                                   where (r1, r2) = raizCuadrada (suma (potencia b 2) (productoEscalar (producto a c) (-4)))
  96. -- Usamos la formula resolvente, con los dos discriminantes usando la función de arriba, que definimos como r1 y r2.
  97.  
  98. -- 3.1
  99. raicesNEsimas :: Integer -> [Complejo]
  100. raicesNEsimas n = [ ( cos(t*(fromIntegral k)), sin(t*(fromIntegral k)) ) | k <- [0..n-1] ]
  101.                   where t = 2*pi/(fromIntegral n)
  102. -- Devolvemos la lista de raices de la unidad para todo k entre 0 y n-1
  103. -- Usamos fromIntegral para convertir el Integer en Float, sino haskell tira error de tipado
  104.  
  105. -- 3.2
  106. sonRaicesNEsimas :: Integer -> [Complejo] -> Float -> Bool
  107. sonRaicesNEsimas n [] e = True
  108. sonRaicesNEsimas n arr e = modulo (suma (potencia (head arr) n) (-1,0)) < e && sonRaicesNEsimas n (tail arr) e
  109. -- 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.
  110. -- Si la lista se vacía, significa que todos los elementos cumplieron con la condición, es decir que son raices de la unidad.
  111.  
  112.  
  113. --Auxilirares
  114. productoEscalar :: Complejo -> Float -> Complejo
  115. productoEscalar (a,b) c = (a*c,b*c)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement