Processing math: 90%

viernes, 2 de marzo de 2012

Pequeña introdución al álgebra geométrica


Operaciones del cálculo vectorial y su simplificación

Supongo que el lector sabe que el cálculo vectorial añade dos operaciones a las propias de un espacio vectorial. Las operaciones propias de un espacio vectorial son el producto por un escalar (\lambda a) y la suma de vectores (a+b). Las añadidas por el cálculo vectorial son el producto escalar (a\cdot b) y el producto vectorial (a\times b).

¿Existirá alguna manera de simplificar este esquema volviendo únicamente a dos operaciones? Bueno, es fácil sobrecargar el producto para que, si uno de sus factores es escalar, se comporte como el producto por un escalar. Ahora queda pensar en cómo aglutinar el producto escalar y el vectorial. La idea básica surge de la forma en la que estos productos tratan los vectores proporcionales y ortogonales.

a y b_\parallel son proporcionalesa\cdot b_\parallel=b_\parallel\cdot aa\times b_\parallel=0
a y b_\bot son ortogonalesa\cdot b_\bot=0a\times b_\bot=-b_\bot\times a

Como todo vector puede ser descompuesto en una parte proporcional y otra ortogonal, lo que tenemos al final es que si b=b_\parallel+b_\bota\cdot b=a\cdot (b_\parallel+b_\bot )=a\cdot b_\parallel+a\cdot b_\bot=a\cdot b_\parallel+0=a\cdot b_\parallela\times b=a\times (b_\parallel+b_\bot )=a\times b_\parallel+a\times b_\bot=0+a\times b_\bot=a\times b_\botSi de alguna manera el nuevo producto fuera similar a una suma de tanto el producto escalar como el producto vectorial, podríamos unificarlos en un mismo producto simplificado al que llamaremos producto geométrico.ab=a(b_\parallel+b_\bot )=ab_\parallel+ab_\botDonde la parte ab_\parallel estará relacionada con el producto escalar y la parte ab_\bot con el producto vectorial. Lo único que hemos requerido es la propiedad distributiva que, de todas las maneras, debe tener un producto lineal.

Debido a que queremos que la parte ab_\parallel siga las propiedades del producto escalar, tendrá que ser simétrica; y debido a que queremos que la parte ab_\bot siga las propiedades del producto vectorial, tendrá que ser antisimétrica: ab_\parallel=b_\parallel aab_\bot=-b_\bot a Y, a partir de ellas llegamos a: ba=(b_\parallel+b_\bot )a=b_\parallel a+b_\bot a=ab_\parallel-ab_\bot Este resultado es muy interesante ya que nos va a permitir obtener la parte relacionada con el producto escalar y la parte relacionada con el producto vectorial a partir del nuevo producto geométrico. ab+ba=2ab_\parallelab-ba=2ab_\botEsta es la idea. Sustituimos dos productos por uno del que, de la forma arriba vista, puede volver a extraerse la información de cada uno de esos dos productos iniciales.

Definiendo el producto geométrico

La forma usual que tenemos de analizar una operación en un espacio vectorial es descomponiendo los vectores como una combinación lineal de los vectores de una base. Bastará ver cómo opera el producto con estos vectores de la base.
Cuando una base \{e_1,e_2,e_3\} de un espacio vectorial V es ortonormal el producto escalar se comporta tal como se expresa en la siguiente tabla de Cayley.
\cdote_1e_2e_3
e_1100
e_2010
e_3001
Esta tabla de Cayley no es más que la abreviatura dee_1\cdot e_1=1,e_1\cdot e_2=0,e_1\cdot e_3=0e_2\cdot e_1=0,e_2\cdot e_2=1,e_2\cdot e_3=0e_3\cdot e_1=0,e_3\cdot e_2=0,e_3\cdot e_3=1Por otra parte, el producto vectorial tiene los siguientes resultados para una base orientada hacia la derecha:
\timese_1e_2e_3
e_10e_3e_2
e_2-e_30e_1
e_3-e_2-e_10
Es importante resaltar aquí que el 0 es el vector nulo y no el escalar nulo.

En el caso del producto geométrico vamos a tener una mezcla de ambos tipos de producto, con ciertas particularidades. La primera es que incluimos el 1 como un componente de la base, ya que queremos subsumir el producto por escalar en el producto geométrico. Esto diluye la diferencia entre el cero escalar y el cero vectorial. El resultado es la siguiente tabla de Cayley.
1e_1e_2e_3
11e_1e_2e_3
e_1e_11e_1 e_2e_1 e_3
e_2e_2e_2 e_1=-e_1 e_21e_2 e_3
e_3e_3e_3 e_1=-e_1 e_3e_3 e_2=-e_2 e_31
Ahora tenemos que pensar qué hacemos con los valores e_1 e_2, e_1 e_3 y e_2 e_3. En el producto vectorial las operaciones con la forma e_1\times e_2=e_3 daban como resultado un vector. Sin embargo, hacer esto con el producto geométrico nos lleva a perder la propiedad asociativa. Si e_1 e_2 = e_3 lo que tenemo es e_1 (e_1 e_2 )=e_1 e_3\ne e_2=(e_1 e_1 ) e_2 Como la propiedad asociativa es necesaria para emular tanto el producto escalar como el vectorial, lo que vamos a hacer es tratar los valores e_1 e_2, e_1 e_3 y e_2 e_3 como fundamentales. No se pueden simplificar. En ese sentido son como e_1,e_2 y e_3 o, también, la propia unidad escalar 1. Es decir, serán componentes de la base del espacio vectorial sobre el que va a operar el producto geométrico. Llamaremos a este espacio \Lambda(V) donde V es el espacio original.

Las signaturas del producto escalar, vectorial y geométrico son: \_\cdot\_:V\times V \to \mathbb{K} \_\times\_ : V\times V \to V \_\ \_:\Lambda(V)\times\Lambda(V)\to\Lambda(V)
Ahora bien, ¿qué componentes tendrá la base de este espacio \Lambda(V)? ¿Faltará alguno más? Podemos volver a repetir el producto sobre e_1 e_2 y obtener cosas como e_1 e_3 e_2 o e_2 e_3 e_1 e_2, lo que ocurre es que al final se simplifican o bien a e_1 e_2 e_3 o a otra de las combinaciones vistas hasta ahora. Lo único que se requiere es asociatividad y la propiedad de elemento neutro escalar 1A=A. e_1 e_3 e_2=e_1 (e_3 e_2 )=-e_1 (e_2 e_3 )=-e_1 e_2 e_3e_2 e_3 e_1 e_2=-e_2 e_3 e_2 e_1=e_2 e_2 e_3 e_1=1e_3 e_1=e_3 e_1Así que, el nuevo espacio vectorial \Lambda(V) donde opera el producto geométrico tendrá la siguiente base.\{1,e_1,e_2,e_3,e_1 e_2,e_1 e_3,e_2 e_3,e_1 e_2 e_3 \} Por ejemplo: El valor 5+4e_1-7e_1 e_3 es un vector de este espacio. Sus coeficientes en la base de arriba serían (5,4,0,0,0,-7,0,0).

Notaremos los elementos de \Lambda(V) con letras mayúsculas A,B,C mientras que continuamos usando las minúsculas a,b,c para los elementos de V y las griegas \alpha, \beta, \gamma para los escalares.

El producto geométrico es cerrado sobre el espacio \Lambda(V) que, a su vez, contiene el espacio V como subespacio vectorial con su base \{e_1,e_2,e_3 \}. La tabla que define el producto geométrico es la que sigue, aunque no es más que lo que hemos visto hasta ahora ampliado a la base completa.
1e_1e_2e_3e_1 e_2e_1 e_3e_2 e_3e_1 e_2 e_3
11e_1e_2e_3e_1 e_2e_1 e_3e_2 e_3e_1 e_2 e_3
e_1e_11e_1 e_2e_1 e_3e_2e_3e_1 e_2 e_3e_2 e_3
e_2e_2-e_1 e_21e_2 e_3-e_1-e_1 e_2 e_3e_3-e_1 e_3
e_3e_3-e_1 e_3-e_2 e_31e_1 e_2 e_3-e_1-e_2e_1 e_2
e_1 e_2e_1 e_2-e_2e_1e_1 e_2 e_3-1-e_2 e_3e_1 e_3-e_3
e_1 e_3e_1 e_3-e_3-e_1 e_2 e_3e_1e_2 e_3-1-e_1 e_2e_2
e_2 e_3e_2 e_3e_1 e_2 e_3-e_3e_2-e_1 e_3e_1 e_2-1-e_1
e_1 e_2 e_3e_1 e_2 e_3e_2 e_3-e_1 e_3e_1 e_2-e_3e_2-e_1-1
Esta tabla (o las propiedades vistas con anterioridad) nos va a servir para calcular el producto geométrico sobre cualquier elemento del nuevo espacio vectorial ampliado.
(5+4e_1-7e_1 e_3 )(e_2+e_1 e_2 e_3 )=5e_2+5e_1 e_2 e_3+4e_1 e_2+4e_2 e_3+7e_1 e_2 e_3-7e_2=
=-2e_2+4e_1 e_2+4e_2 e_3+12e_1 e_2 e_3
Curiosamente, el valor e_1 e_2 e_3 cumple que (e_1 e_2 e_3 )^2=-1. Por similitud con la unidad imaginaria se nota con I=e_1 e_2 e_3 y se le da el nombre de pseudoescalar. Si nos restringimos a vectores de \Lambda(V) de la forma \alpha+\beta I, todo el cálculo complejo aparece en este subespacio.
Así que el producto geométrico no sólo aúna los productos escalares y vectoriales, sino que también los números complejos.

Sorpresas algebraicas

El producto geométrico de un vector a de V por sí mismo es un escalar, y además positivo. Obviamente, llamaremos esta multiplicación por sigo mismo, potenciar al cuadrado.a^2=(\alpha_1 e_1+\alpha_2 e_2+\alpha_3 e_3 )(\alpha_1 e_1+\alpha_2 e_2+\alpha_3 e_3 )=\alpha_1^2+\alpha_2^2+\alpha_3^2 Eso significa que se puede definir la inversa de un vector respecto al producto geométrico. a^{-1}=a/a^2 Se comprueba que, efectivamente, es una inversa. Basta con tener cuidado de saber que a^2 es un escalar y por eso podemos calcular 1/a^2 en el cuerpo de V.

Aunque todos los vectores no nulos de V tienen inversa, no todos los elementos del espacio completo \Lambda(V) tienen inversa. Por ejemplo, 1+e_1 no la tiene ya que es un divisor de cero (1+e_1 )(1-e_1 )=1-e_1+e_1-1=0. Si tuviera inversa llegaríamos a que 1-e_1=0 lo cual es contradictorio.

Un uso inmediato de la inversa de vectores es la obtención de la parte proporcional y la parte ortogonal de un vector respecto a otro.b_\parallel=a^{-1} ab_\parallel=a^{-1} (ab+ba)/2b_\bot=a^{-1} ab_\bot=a^{-1} (ab-ba)/2Podemos seguir potenciando vectores a^k=aa^(k-1). Sin embargo, nos encontramos con una propiedad muy interesante cuando potenciamos cualquier elemento de la base de \Lambda(V).
E=1e_1e_2e_3e_1 e_2e_1 e_3e_2 e_3e_1 e_2 e_3
E^0=11111111
E^1=1e_1e_2e_3e_1 e_2e_1 e_3e_2 e_3e_1 e_2 e_3
E^2=1111-1-1-1-1
E^3=1e_1e_2e_3-e_1 e_2-e_1 e_3-e_2 e_3-e_1 e_2 e_3
E^4=11111111
E^5=1e_1e_2e_3e_1 e_2e_1 e_3e_2 e_3e_1 e_2 e_3
Así que, para los elementos de una base ortonormal de \Lambda(V),E^k=E^{k+4} Y, en concreto, se pueden definir las potencias negativas de estos elementos mediante esta propiedad. Desafortunadamente, aunque existe sin problemas, la expresión general de potenciación es bastante más tediosa y no cumple la propiedad de involución arriba vista. Por ejemplo, (1+e_1 )^k=2^k (1+e_1 ).

Tener un producto geométrico cerrado en \Lambda(V) permite definir la exponencial en este espacio.\exp(A)=\sum_i{\frac{A^i}{i!}} Es fácil comprobar que \exp(a+b)=\exp(a)\exp(b). Además, gracias a la involución de los vectores de la base de \Lambda(V) llegamos a las siguientes ecuaciones:\exp(\alpha)=\cosh(\alpha )+1 \sinh(\alpha )=e^α\exp(\alpha e_i )=\cosh(\alpha )+ e_i \sinh(\alpha )\exp(\alpha e_i e_j )=\cos(\alpha )+e_i e_j \sin(\alpha )\exp(\alpha I)=\cos(\alpha )+I \sin(\alpha ) Esta última expresión no es otra que la fórmula de Euler. Además, la penúltima expresión nos da a entender que los elementos de la forma \exp (\alpha e_i e_j ) tienen algo que ver con las rotaciones.

Como ocurría con la potenciación, la exponenciación de elementos generales de \Lambda(V) no es inmediata y requiere bastantes cálculos. Sin embargo, para vectores \exp \left(\sum_{i=1}^3{\alpha_i e_i}\right)=\prod_{i=1}^3{[\cosh (\alpha_i )+e_i \sinh (\alpha_i ) ]}

Sorpresas geométricas

Probemos a usar \exp(\alpha e_1 e_2 ) para intentar rotar un vector con la intuición que hemos ganado arriba. En el caso de \alpha=\pi/2 la expresión de arriba nos dará \exp \left(\frac{\pi}{2} e_1 e_2 \right)=e_1 e_2=R Este valor R no rota de por sí un vector. Sin embargo, la expresión –RaR sí consigue lo que queríamos, aunque el ángulo de la rotación es el doble (debido a que hay dos R).

Por ejemplo, en el caso de querer rotar e_3, si estamos rotando en el plano formado por e_1 e_2, el resultado ha de ser invariante. Efectivamente:-Re_3 R=-e_1 e_2 e_3 e_1 e_2=-e_1 e_2 e_1 e_2 e_3=e_3 Por otra parte, rotar un vector a en el plano e_1 e_2 media vuelta debe ponerlo en la posición -a.-RaR=-e_1 e_2 (\alpha_1 e_1+\alpha_2 e_2 ) e_1 e_2=-(\alpha_1 e_1 e_2 e_1 e_1 e_2+\alpha_2 e_1 e_2 e_2 e_1 e_2 )=-a Así que la expresión para rotar un ángulo \theta un vector a en el plano formado por los vectores ortonormales b y c es -\exp\left(\frac{\theta}{2}bc\right)a \exp\left(\frac{\theta}{2} bc\right)=-RaR
Simple.

¿Qué ocurre si en vez de usar un valor R=bc usamos un R=b? Lo que obtenemos entonces es una reflexión. Es sencillo observar que si R=e_1 entonces R e_1 R=e_1,R e_2 R=-e_2,R e_3 R=-e_3RaR=R(\alpha_1 e_1+\alpha_2 e_2+\alpha_3 e_3 )R=\alpha_1 e_1-\alpha_2 e_2-\alpha_3 e_3 Esto último no es más que la simetría en el eje de la dirección e_1. Se puede generalizar a cualquier vector unitario y, además, coincide con la idea intuitiva de que una rotación es equivalente a dos reflexiones.

Pensamientos finales

Quedan muchas más cosas por descubrir en el álgebra y el cálculo geométrico. Por ejemplo, se unifican los operadores diferenciales de gradiente, divergencia y rotacional a un único operador diferencial que los engloba. Sin embargo, este artículo ya está quedando largo y sólo me queda dirigir al lector a la Wikipedia y los libros que allí se referencian.

lunes, 13 de febrero de 2012

miniSL parte 18 - Funciones auxiliares del escaneador léxico

En la entrada anterior usamos SkipWhitespace() que automágicamente se saltaba todos los caracteres en blanco hasta el siguiente carácter. La función no es realmente complicada y se limita a ir observando con peek() el siguiente carácter para tirarlo con get() si es un espacio en blanco.

La única variación va a ser el reconocimiento de comentarios. Los comentarios empiezan con un # y terminan con el final de línea.

void Script::SkipWhitespace(ISTREAM& i)
{
 while(i.good() && unsigned(i.peek())<256 && (iswspace(i.peek()) || i.peek()=='#'))
 {
  if(i.peek()=='#')
  {
   i.get();
   while(i.good() && i.peek()!='\n')
    i.get();
  }
  else
   i.get();
 }
}

Es importante dejar claro aquí que no vamos a soportar UNICODE (ni siquiera el famoso "pila de caca") y cualquier carácter por encima del 255 será considerado extraño. De ahí la condición en la guarda del bucle.

Trabajar con iostreams es un poco pesadilla porque no usa excepciones para cosas que deberían ser excepciones (de hecho, los gurús del C++ se quejan a menudo de esta parte de la biblioteca estándar). Poco más podemos hacer para remediarlo que ir comprobando con i.good() cada vez.

Otra función que se usará de vez en cuando es la que espera consumir un token raw (un carácter) en concreto. Es muy simple.

void Script::ConsumeRawToken(ISTREAM& i, ISTREAM::int_type c, wchar_t const* msg)
{
 TOKEN t=ReadToken(i);
 if(t.type!=T_RAW || t.raw!=c)
  throw msg;
}

Si el carácter no es el esperado, lanzamos una excepción con el mensaje. Como hablamos de caracteres, el token ha de ser T_RAW.

Con esto acabamos las funciones auxiliares y pasamos a la lectura de cadenas en la siguiente entrada.

jueves, 19 de enero de 2012

Pasos en la profesión

Una idea que quiero concretar antes de que se me olvide.
  1. Sueños: En este momento sólo se tienen ideas de la profesión. Suele ocurrir cuando se es aún un niño.
  2. Realización: Las ideas se concretan en obras. Si se quería ser alfarero, se realizan las primeras vasijas. Si se quería ser programador, se terminan los primeros programas.
  3. Estudio: Siempre me ha llamado la atención que, sea cual sea la disciplina que se estudie, siempre hay una grandísima cantidad de temas de estudio. Ni que decir tiene que para progresar en la profesión, hay que estudiar. Aunque tampoco demasiado porque si no, no pasamos al siguiente punto.
  4. Práctica: Generalmente el resultado de la realización de ideas no es lo que se tenía en mente. Hay que practicar para que el abismo entre imaginación y realidad se haga más somero. Este es el paso más difícil desde mi punto de vista, ya que se debe trabajar mucho pero no hay realimentación de resultados.
  5. Mercado: Llega un momento en el que las obras realizadas se pueden mostrar al público e, incluso, algunas, vender. Estamos tocando el mercado. Empieza a haber resultados.
  6. Profesión: Es cuando se pueden obtener ingresos regulares de lo que se crea y esos ingresos son suficientes para vivir.
  7. Reconocimiento: El trabajo que se realiza es reconocido entre los que se dedican a lo mismo.
  8. Éxito: Simplemente, los ingresos son muy superiores a lo que se necesita para vivir. Si se dejase de trabajar, seguiríamos teniendo ingresos por regalías o licencias.
  9. Fama: El trabajo que se realiza es reconocido entre los que no se dedican a lo mismo.
  10. Inmortalidad: El trabajo que se realiza sigue siendo reconocido generaciones después.
Es interesante dar un factor de filtrado a cada paso. Así, si de cada 10 que tienen ideas, 1 las realiza; el factor es de 10. De realización a práctica el factor puede ser de 5, pero de práctica a mercado creo que es 20 o más. De mercado a profesión puede ser de 5 o así. Es decir que, a bote pronto, una de cada 5000 personas puede vivir de sus sueños.

Es una estimación algo burda, pero tomándolo como un problema de Fermi el resultado nos puede dar a ver la dificultad de la tarea.