jueves, 15 de septiembre de 2016

De lógica

Puntos a tratar:

  1. Todo estaría esencialmente en orden, pero no está demás dar un repaso general y lo siguiente.
  2. No vimos esto de la "diferencia simétrica" entre conjuntos, ya que supuse que estaba basada directamente en las tres operaciones fundamentales: unión, intersección y diferencia de conjuntos. Repasar la definición en la red o en algún libro.
  3. Repasar demostraciones: captar la idea de convencer a alguien de que estamos en lo correcto.
  4. Dar prioridad a los tipos de razonamiento sobre, por ejemplo, inducción matemática.
Mucha suerte.

martes, 5 de julio de 2016

Directivas generales (nuevas)

Nuevo: No espero más aclaraciones, verificaciones y revisiones, así que lo que
sigue es enfocarse, a quienes así convenga, a su 2o. extraordinario, el cual
tomará en consideración el material ya visto junto con algún par de ejercicios
del teorema de Stokes o el de Green. Menciono que tomar dxdy o dydx de una
integral iterada dependera de la simetría del dominio, así que es necesario
tomar en consideración si los barridos son de arriba hacia abajo (forma dydx)
o de derecha a izquierda (forma dxdy).

Para el ejemplo del examen, tendríamos
    2     sqrt(x)
int   int            f(x,y) dy dx
    0      0

y la otra versión (que nadie hizo) es:
    sqrt(2)      2
int            int         f(x,y) dx dy
      0             y*y

Verificando en máxima, tenemos:
(%i6) integrate(integrate(y/(1+x**2),y,0,sqrt(x)),x,0,2);
                                    log(5)
(%o6)                               ------
                                      4


(%i9) integrate(integrate(y/(1+x**2),x,y*y,2),y,0,sqrt(2));
     2
Is y  - 2 positive, negative or zero?

positive;
                                    log(5)
(%o9)                               ------
                                      4

Nuevo (12 de julio de 2016): Ya pueden verificar su calificación en el sistema.
Las aclaraciones sólo serán el día de hoy, de preferencia de 4 a 7.


Nuevo: Tomar en consideración que este examen será colegiado
(departamental), así que se intentará mantener un conjunto básico
de problemas por mi parte, pero otros más pueden venir de otros profesores.
Para este caso, repasar de algunos libros clásicos de cálculo diferencial
e integral.

Nuevo: El examen será el lunes 11 de julio en los salones A9 y A10 de 9 a 11
de la mañana.


El examen está dividido en tres partes:

a) Sería la parte de integración simple:
  1. Integración por partes
  2. Integración por sustitución
  3. Fracciones parciales (por ejemplo: int 1/(x**2+x) dx).
  4. Con integración indefinida.
  5. Manejo de integrales (1/(1+x**2))... sinh x, cosh x, e**x (por cierto, es posible que no se permita el uso de formularios en el examen; recordar algunas fórmulas básicas es, así, indispensable para trabajar sin formularios: escribir unas cuantas veces en un papel las fórmulas trigonométricas varias veces es útil, así como "jugar" con las fórmulas de integración: por ejemplo, la integral de 1/(1+x**2) es... y así en una ronda de memorización).
Advertencias en esta parte: No realizar "operaciones de estudiante novato":
i) 1/(a+b) =/= 1/a+1/b
ii) (a**2)**3 =/= a**5
iii) a**3*a**2 =/= a**6
iv) sqrt(a+b) =/= sqrt(a) +sqrt(b)
v) int (f(x)*g(x)) dx =/= (int f(x) dx) * (int g(x) dx)
x/x =/= 1   (la primera tiene una indefinición en x=0; la igualdad es válida si garantizamos que x=/=0)
Agregando otra falacia:
 vi)  (a+b)**2=a**2+b**2

El caso de las fracciones parciales es también digno de estudiar por sí mismo,
ya que de un denominador complicado se puede pasar a un denominador simple, permitiendo que se aplique alguna fórmula de integración bien conocida (por ejemplo, logaritmos):
Ejemplo sencillo:
1/(x**2-5x+6)=
1/[(x-2)(x-3)]=A/(x-2)+B/(x-3)
y
A/(x-2)+B/(x-3)=(A(x-3)+B(x-2))/[(x-2)*(x-3)]
por lo que
1/[(x-2)(x-3)]=(A(x-3)+B(x-2))/[(x-2)*(x-3)] implica que debemos tener
1=A(x-3)+B(x-2)=Ax+Bx-3A-2B= x(A+B)-3A-2B
Si los polinomios 1 y  x(A+B)-3A-2B deben ser iguales, tendrían que
ser iguales por cada ocasión en que ocurre o no la variable x; así,
1=-3A-2B (*)
A+B=0
De aquí, B=-A, y sustituyendo en (*)
 1=-3A+2A=-A, de donde A=-1, y por lo tanto B=1.
De lo anterior, debería ser cierto que
1/[(x-2)(x-3)]=-1/(x-2)+1/(x-3)
 -1/(x-2)+1/(x-3)=[(3-x)+(x-2)]/[(x-2)(x-3)]=1/[(x-2)(x-3)],
como era requerido.
Lo importante es que integrar esta nueva versión
-1/(x-2)+1/(x-3)

es algo sencillo.



Recordemos además que no está de sobra repasar la factorización de un polinomio, la división de polinomios y la suma y resta. Las prisas o los nervios

a veces nos hacen cometer errores simples en estas operaciones. Es bueno en apartar las operaciones que así se realicen para después complementarlas con los ejercicios que se trabajen.

Cuando el tiempo lo permita, traten siempre de derivar aquella función
que proponen como solución en la integración: se tiene que llegar a la
función original, por el teorema fundamental de cálculo.
Noten también que la definición es:
     b
int   f(x) dx = F(b) - F(a), donde F'(x)=f(x), y no F(a) - F(b)
     a
Alterando el orden se cambia el signo, y puede llevarlos a conclusiones
erróneas.

b) Integrales dobles
  1. Descripción de regiones (arriba a abajo, o izquierda a derecha).
  2. Integrales iteradas; consideraciones sobre las variables.
  3. Integrales dobles sobre regiones.
  4. Teorema de Fubini.
  5. Evaluaciones de integrales sobre regiones con definiciones incluyendo constantes: ejemplo [0,a]x[0,b], con a>0,b>0. 
En el caso de regiones, debe distinguirse bien cómo se caracterizan:
para los casos básicos, es de arriba a abajo (primero dy) o de derecha a
izquierda. No es "conmutativo" este orden!!! (salvo casos simétricos indistinguibles). Por ejemplo, integrando f(x,y)=x*2 en [0,2]x[0,2]
es lo mismo para esta región si evaluamos
     2             2
int          int      f(x,y) dy dx     o si evaluamos
      0            0
     2             2
int          int      f(x,y) dx dy
      0            0

pero no para cuando la región es [0,1]x[0,2].

c) Repasar de Larson, parte de cálculo vectorial.
  1. Gradientes.
  2. Campos vectoriales.
  3. Dominios y codominios.
  4. Rotacional.
  5. Divergencia.
  6. Producto interno.
  7. Producto externo.
  8. Integrales de línea; integrales de longitud de arco.
  9. Repasadita del Teorema de Stokes, de Green. 
En esta parte los errores comúnmente registrados son los de ausencia
de paréntesis, tanto para dar adecuada prioriada al efecto de los operadores
como para señalar con precisión que se trabaja con vectores de cierta dimensión. Además, otro error común en los exámenes previos fue no identificar
los pasos de evaluación finales. A veces es una pena que ya se obtuvieron
en esencia los resultados correctos pero las malas evaluaciones subsiguientes
echan todo a perder.

Un tema en el que muchos fallaron en el examen ordinario fue el de cómo
ensamblar la función potencial f de un campo vectorial conservativo F.

Sea por ejemplo F(x,y)=(x,y)
ya que la derivada parcial de x con respecto a y es 0, y de la derivada
parcial de y con respecto a x es también 0, el campo F es conservativo.
devParcial(f,x)=x implica que f1(x,y)=x**2/2+C1(y)
para una f1(x,y) (incompleta con respecto a f).
devParcial(f,y)=y implica que f2(x,y)=y**2/2+C2(x)

Ahora bien, debemos tener que f1=f2=f!, es solo que f es la que abarca
a f1 y a f2. Pero, por un lado, C1(y) puede ser y**2/2 (que está en la formulación de f2), y por otro C2(x) puede
ser igual a x**2/2, (que está en la formulación de f1)
así que f "completa" es f(x,y)=x**2/2+y**2/2+ C, donde
ahora sí C no tiene compromiso de tener dependencia con respecto a x o
a y: es una constante cualquiera.

C1(y) depende de y, pero al derivarla con respecto a x es 0, así que
C1(y) sí depende y; análogamente para C2(x).

Lo mejor para ver que uno dió la respuesta correcta es verificar que con la
f ensamblada se cumple que grad f = F!!!!
Notemos que para todo lo anterior el antecedente previo es la buena técnica de derivación, y el considerar como bien dominado el concepto de derivada parcial (sin cambiar notaciones bien establecidas).

jueves, 29 de octubre de 2015

Fibonaccis y coálgebras en Haskell


Este es un archivo en modo "Haskell literario"

> x = 2
> y = (\x -> x+2) 2

"Naked expression... ", manejo de este tipo de errores.

Veamos la siguiente álgebra:
<<(+,1)>> = Naturales.
El elemento primigenio, seminal o generador es el 1, y la operación de generación
es el +.

1, 1+1=2, 1+1+1=3, 3+1, ...
1, 2, 3, ...                          
-- #N Cardinalidad de N: El tamaño del conjunto generado. La ocurrencia de un $n$
dentro de la sucesión es su orden (como conjunto ordinal).

Otro ejemplo:
<<({o, y, no},{F,T})>> = Proposiciones lógicas simples con constantes T y F.

F,T,T o F, (T o F) y (no F),...
Cfr. con Prolog.

?- false.
false.

?- true,false.
false.

?- true,true.
true.

?- \+ (true).
false.

?- false < true.
ERROR: </2: Arithmetic: `false/0' is not a function -- ya que < es definido para aritmética
?- false @< true.
true.  --ya que @< compara términos

-----------------------------------------------------------------------------

Para coálgebras:

[1],  %Primer elemento
[1,1], % segundo elemento
[1,1,1]...

en el paso al límite en el crecimiento de esta sucesión tenemos un
elemento "infinito": sería el "último" de una unión de elementos previos:

A1={[1]}
A2= A1 U {[1,1]}
A3= A2 U {[1,1,1]}
....
An = A(n-1) U {[1...replicado n veces]} (U representa la unión de conjuntos)
 A1 C A2 C A3 C A4 C A5 C ... ----> infinito (C representa la contención de conjuntos)

En el paso al límite (cuando n tiende a infinito), tenemos un conjunto infinito, cuyo
´ultimo elemento se dice que ésta en la coálgebra generada por la sucesión An.

Para el ejemplo tratado, se especifica en Haskell así:

> o = 1:o

En el modelo de computación de Haskell que es por medio de evaluación perezosa
un elemento solo se crea si se requiere en un paso de cómputo.

Así se crean los números naturales  a partir de un número n:

> nat n = n: nat(n+1)

Y así se crean todos los números naturales

> l = nat 1

Tomando l, tenemos
[1,2,3,4,5,6...] (infinitamente.

Consideremos ahora la función de Fibonacci y observemos que
si desplazamos la sucesión de Fibonacci con respecto a sí misma y
sumamos columna a columna tenemos otra vez la función de Fibonacci:
1,1,2,3,5,8...
   1,1,2,3,5,8...
____________
1 2 3 5 8 13...
Esto diría que la sucesión  de Fibonacci es más fácil de crear subcreando
dos sucesiones de Fibonacci que creando una sola! Paradójico,  no?


> fibs0 = [1,1,2,3]
> fibs1 = 1:1:[]
> fibs2 = 1:1:[x+y| x <- fibs0, y <- tail fibs0]

x valor 1 y valor 1
x valor 1 y valor 1

Tarea: Generar los números primos por medio de un flujo (comento el cofinal
de una coálgebra).


Si ahora tenemos:
fibs
obtenemos
[1,1,2,3,4,2,3,4,3,4,5,4,5,6]
que no es lo que se desea.

*Main> [x+y | x<-[1,2,3,4],y<-[5,6,7]]
[6,7,8,7,8,9,8,9,10,9,10,11]
*Main> [(x,y) | x<-[1,2,3,4],y<-[5,6,7]]
[(1,5),(1,6),(1,7),(2,5),(2,6),(2,7),(3,5),(3,6),(3,7),(4,5),(4,6),(4,7)]

Hagamos justa (fair) la selección de elementos (1 elemento por lista en cada
ocasión). Utilizamos para ello la función zip:

*Main> zip [1,2,3,4] [5,6,7]
[(1,5),(2,6),(3,7)]

*Main> [(x,y) | (x,y)<-zip [1,2,3,4] [5,6,7]]
[(1,5),(2,6),(3,7)]

*Main> [x+y | (x,y)<-zip [1,2,3,4] [5,6,7]]
[6,8,10]

Finalmente, esta es la función requerida:

> fibs = 1:1:[x+y | (x,y) <- zip fibs (tail fibs)]

He aquí algunas ejecuciones:

*Main> take 5 fibs
[1,1,2,3,5]
*Main> take 8 fibs
[1,1,2,3,5,8,13,21]
*Main> take 12 fibs
[1,1,2,3,5,8,13,21,34,55,89,144]
*Main> take 15 fibs
[1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
*Main> take 20 fibs
[1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]
*Main> fibs!!100
573147844013817084101
*Main> fibs!!200
453973694165307953197296969697410619233826

etc.

miércoles, 28 de octubre de 2015

Haskell es especial



*.lhs: Hacen a Haskell intensivamente comentado.

Haskell: Su fundamento es el Cálculo Lambda (Alonzo Church, 1930s).
Haskell: Bloque de trabajo son las funciones (brazo derecho).
Haskell: Los tipos son su brazo izquierdo de trabajo: Char, Int, Float, Double...
              tipos curriados o compuestos vía productos cartesianos.
Haskell: Mónadas: La manera de Haskell de modelar el mundo exterior
               disciplinadamente.
Haskell: Funciones de mayor orden y funciones curriadas.
Haskell: Estrategia genérica de evaluación perezosa (lazy evaluation), lo que
         origina coálgebras: Las coálgebras son estructuras duales a las álgebras.
         En una álgebra queremos la intersección de inclusión; en una coálgebra
         queremos la unión de la inclusión. Las coálgebras permiten justificar la
         introducción y utilizamiento de algo conocido como objetos computacionales
         infinitos.


Ejemplos:
1) Cálculo lambda:

> (\x -> x+1) 2
> map (\x -> (4:)) [[1],[2],[3]]

>  map (\x -> x*x) [1,2,3]

> let s = sin . cos in s 2
> let f = tan . cos . sin in f 10

(Haciendo eco de las palabras del Premio Turing John Backus, de que las
variables son inútiles en la programación.)
El operador punto es composición de funciones.

2) Bloques (sin variables)

> longitud  = sum . unos
> unos = map (\x -> 1)


3) Tipos:

> lonCad :: String -> Int
> lonCad = length

Aquí se enfatiza que lonCad calcula la longitud de cadenas.

4) Visto como el programa Hello.hs.

> filter (\x -> x> 10) [1..100]

A las funciones que toman como argumento a otras funciones se les llama
funciones de mayor orden.

> productoInterno:: ((Float,Float),(Float,Float)) -> Float
> productoInterno ((x1,y1),(x2,y2)) = x1*x2+y1*y2




> productoInterno':: (Float,Float) -> (Float,Float) -> Float
> productoInterno' (x1,y1) (x2,y2) = x1*x2+y1*y2

> productoInterno'':: Float ->Float -> Float -> Float -> Float
> productoInterno''  x1 y1 x2 y2 = x1*x2+y1*y2

> mul2 :: (Float, Float) -> Float
> mul2 (x,y) = x*y+2

Versión curriada (Haskell Curry)

> mul2' :: Float -> Float -> Float
> mul2' x y = x*y+2

map (mul2 2) [1,2,3,4,5]

map (\x -> (mul2 (2,x))) [1,2,3,4,5]
La diferencia es que mul2 trabaja en el dominio (Float,Float) y
y mul2' trabaja en el dominio Funciones: Float -> Float

Esta es la versión (infame) de un programa para crear los
números de Fibonacci.
> fib 1 = 1
> fib 2 = 1
> fib n | n> 2 = fib             (n-1) + fib                 (n-2)
En una próxima ocasión generaremos su versión de flujo.


Mientras, la siguiente función genera un flujo infinito de filas del triángulo de Pascal:

> pascal = p
>   where
> p = [1] : [next a | a <- p]
> next x =  addRows (0:x) x
>                  where
>            addRows (a:x) (b:y) =  (a + b):(addRows x y)
>            addRows [a]   []    =  [a]
>            addRows []    []    =  []

Como ejemplos de ejecución tenemos:

Main> take 5 pascal
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
*Main> take 15 pascal
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1],[1,6,15,20,15,6,1],[1,7,21,35,35,21,7,1],[1,8,28,56,70,56,28,8,1],[1,9,36,84,126,126,84,36,9,1],[1,10,45,120,210,252,210,120,45,10,1],[1,11,55,165,330,462,462,330,165,55,11,1],[1,12,66,220,495,792,924,792,495,220,66,12,1],[1,13,78,286,715,1287,1716,1716,1287,715,286,78,13,1],[1,14,91,364,1001,2002,3003,3432,3003,2002,1001,364,91,14,1]]
*Main> pascal!!4
[1,4,6,4,1]
*Main> (pascal!!4)!!3
4

lunes, 26 de octubre de 2015

Es sencillo, con mónadas



---------------- Y ahora lo siguiente
main :: IO ()
main = do
  putStrLn "Cuál es tu nombre?"
  name <- getLine
  putStrLn ("Gusto en conocerte, " ++ name ++ "!")

--- main tiene tipo IO (): las acciones posibles para cambiar un mundo.
--- do permite realizar acciones secuencialmente
--- Cada acción es ejecutada dentro de la mónada

--- ¿Por qué esto tendría que ser tan difícil? ¿No es este programa una nadería en la
--- programación imperativa?

--- La respuesta es: Se requiere controlar cada efecto lateral, se requiere que el programador
--- sea consciente de cada valor de una expresión, y además se requiere que haya un orden
--- para realizar consecutivamente cada acción. En resumen, se requiere control.
--- Y es que de otra forma la programación (de computadoras) permite fácilmente, sin disciplina,
--- la creación de monstruos amorfos, gelatinosos, escurridizos y fantasmagóricos: son esos
--- programas convencionales que de pronto fallan sin saber por qué, que son difíciles de dar
--- mantenimiento, de actualizar o de ampliar. Sin control, un programador entra fácilmente en
--- un terreno minado.