Expresión analítica y geométrica del producto escalar

El producto escalar es una operación entre dos vectores que retorna un escalar, es decir, un número real. Existen dos definiciones de esta operación que darán el mismo resultado, aunque inicialmente no sea muy intuitivo que así sea: la analítica y la geométrica. Veamos la primera de ellas:

Dados dos vectores del espacio vectorial ℝn, u = (u1, u2, …, un) y v = (v1, v2, …, vn), se define el producto escalar de ambos, u · v como:

u·v = u1 · v1 + u2 · v2 + … + un · vn

En todo espacio vectorial euclídeo, y por lo tanto normado, podemos usar también la definición geométrica, esta nos dice que el producto escalar de dos vectores es el producto del módulo (o norma) de cada uno de ellos por el coseno del ángulo que forman:

Producto escalar

(2)

A continuación, veamos dos ejemplos sencillos en el plano cartesiano, ℝ2, para ver que ambas formas arrojan el mismo resultado. Ya nos advirtió Johan Cruyff: “Un palomo no hace verano”, por lo que estos dos ejemplos no pretenden demostrar nada sino ejemplificar este concepto poco intuitivo. El primer ejemplo consistirá en los vectores u = (2, 2) y v = (2, -2):

ejemplo 1El ángulo entre ambos es, obviamente, 90º, pues cada uno hace un ángulo de 45º con el eje de las abscisas. Como cos(90º) = 0, según la segunda definición el producto escalar también es 0, pues cualquier número multiplicado por 0 es 0. El mismo resultado obtenemos con la forma analítica:

u·v =2·2 + 2·(-2) = 4 – 4 = 0

El segundo ejemplo estará constituido por los vectores u = (1, 1) y v = (2, 0):

Segundo ejemploEn este caso, el ángulo entre ambos es de 45º. El coseno de 45º es √2 / 2, no es tan redondo como el anterior, no obstante, ambas definiciones deben coincidir:

u·v = 1·2 + 1·0 = 2

Para poder calcular según la segunda definición necesitamos saber, en primer lugar, el módulo o norma de cada vector:

modulo de umodulo de vEfectivamente, coinciden:

con cosenoFinalmente, destacar dos aspectos de la definición geométrica. El primero de ellos es que nos permite obtener el ángulo que forman dos vectores pues, obviamente, al aislar el coseno en la ecuación (2) obtenemos:

angulo de dos vectores

(3)

El segundo es que la interpretación geométrica del producto escalar de dos vectores es la proyección de uno sobre otro multiplicada por el módulo de este último. Con los vectores del último ejemplo, u = (1, 1) y v = (2, 0), la proyección de u sobre v sería:

proyeccion de u sobre v

w es la proyeccion de u sobre v

w es un vector cuyo modulo es la distancia desde el origen hasta la proyección de u sobre v; la podemos calcular mediante trigonometría básica:

resiltado de la proyeccion de u sobre v

Atención: el módulo de w no es el producto escalar entre u y v. Para que lo sea, es necesario multiplicar por el módulo del segundo (v):

Siendo esta exactamente la definición geométrica que vimos en la ecuación (2). En definitiva, podemos ver que:

Producto vectorial con proyección de vectores

Producto vectorial con proyección de vectores

Donde:

Proyección de u sobre v

Proyección de u sobre v

Esta fórmula no sale de la nada (aunque sí habrá salido en muchas chuletas), acabamos de ver que el vector w es la proyección del vector u sobre v, como sabemos que:

Por (3):

Para aislar el módulo de w, olvidémonos del coseno y centrémonos en la segunda y tercera igualdad: multiplicando por el módulo de u en ambos lados de la ecuación nos resulta la fórmula de la proyección de u sobre v:

A modo de anécdota, para saber cuál es el vector w, debemos calcular el vector unitario de v, pues ambos van en la misma dirección, y multiplicarlo por |w|.

Cómo simplificar una relación Many-To-Many consigo misma

En esta breve entrada expongo cómo el programador puede facilitarse un poco su actividad cuando en Doctrine establezca una relación de una entidad consigo misma. El código que se expone es de una entidad del framework Symfony, pero fácilmente se puede adaptar a cualquier entorno PHP donde, eso sí, se esté empleando este conocido ORM.

Según la documentación de Doctrine, el código para la relación Many-To-Many (de muchos a muchos) de una entidad que se referencia a si misma, por ejemplo un producto que puede tener otros productos relacionados, sería:

class Product
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ManyToMany(targetEntity="Product", mappedBy="myProducts")
     */
    private $relatedWithMe;

    /**
     * @ManyToMany(targetEntity="Product", inversedBy="relatedWithMe", fetch="EAGER")
     * @JoinTable(name="related_products",
     *      joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="related_product_id", referencedColumnName="id")}
     *      )
     */
    private $myProducts;

    public function __construct()
    {
        $this->relatedWithMe = new ArrayCollection();
        $this->myProducts = new ArrayCollection();
    }

    public function addRelatedWithMe(Product $relatedWithMe): self
    {
        if (!$this->relatedWithMe->contains($relatedWithMe)) {
            $this->relatedWithMe[] = $relatedWithMe;
            $relatedWithMe->addMyProduct($this);
        }

        return $this;
    }

    public function removeRelatedWithMe(Product $relatedWithMe): self
    {
        if ($this->relatedWithMe->contains($relatedWithMe)) {
            $this->relatedWithMe->removeElement($relatedWithMe);
            $relatedWithMe->removeMyProduct($this);
        }

        return $this;
    }

    /**
     * @return Collection|Product[]
     */
    public function getMyProducts(): ?Collection
    {
        return $this->myProducts;
    }

    public function addMyProduct(Product $myProduct): self
    {
        if (!$this->myProducts->contains($myProduct)) {
            $this->myProducts[] = $myProduct;
        }

        return $this;
    }

    public function removeMyProduct(Product $myProduct): self
    {
        if ($this->myProducts->contains($myProduct)) {
            $this->myProducts->removeElement($myProduct);
        }

        return $this;
    }

Esta estructura con dos propiedades presenta un inconveniente: las consultas a la base de datos para buscar todos los productos relacionados pueden ser algo más complejas pues si, por ejemplo, el producto 1 está relacionado con el 2, el ser bidireccional implica que el 2 también lo está con el 1, pero en la tabla pivote related_products sólo tendremos el registro (1, 2) o el (2, 1).

Una solución que nos permite mantener las consultas a la base de datos sencillas y un código PHP nítido, es crear una relación unidireccional con un “truco” o hack de tan sólo dos líneas:

class Product
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ManyToMany(targetEntity="Product")
     * @JoinTable(name="related_products",
     *     joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
     *     inverseJoinColumns={@JoinColumn(name="related_product_id", referencedColumnName="id")}
     *      )
     */
    private $relatedProducts;

    public function __construct()
    {
        $this->relatedProducts = new ArrayCollection();
        $this->stamps = new ArrayCollection();
    }

    /**
     * @return array
     */
    public function getRelatedProducts()
    {
        return $this->relatedProducts->toArray();
    }

    /**
     * @param  Product $product
     * @return void
     */
    public function addRelatedProduct(Product $product)
    {
        if (!$this->relatedProducts->contains($product)) {
            $this->relatedProducts->add($product);
            $product->addRelatedProduct($this);
        }
    }

    /**
     * @param  Product $product
     * @return void
     */
    public function removeRelatedProduct(Product $product)
    {
        if ($this->relatedProducts->contains($product)) {
            $this->relatedProducts->removeElement($product);
            $product->removeRelatedProduct($this);
        }
    }

La primera línea marcada en negrita es la que inserta el segundo registro en la base de datos; de manera que para consultar los productos relacionados de un producto no tendremos que consultar dos propiedades. El precio a pagar será que en la tabla tendremos datos que podrían considerarse duplicados, pero hará la programación más sencilla y, de todas formas, con un ORM no se puede ser muy escrupuloso con las formas normales.

Esta idea también podría aplicarse al ejemplo inicial, pero si añadimos ambos registros para simplificar las consultas, entonces nos encontramos con que se añade complejidad a la clase pues ambas propiedades, $myProducts y $relatedWithMe, se deberían mantener sincronizadas y actualizadas.

Por lo tanto, esta relación unidireccional de una entidad consigo misma, aunque no aparece en la documentación oficial, es una solución que nos permite crear un código más claro y más fácil de mantener.

Preferencia de las operaciones según Casio

Por la preferencia de operadores, así resolvemos la siguiente operación:

O también:

Ahora bien, la Casio fx-83ES Plus opina diferente:

Casio Fx 82ES PLUS error por la preferencia de operaciones

En primer lugar calcula el paréntesis para, a continuación, multiplicarlo por el denominador, resultado que, finalmente, dividirá el numerador.

En cambio, curiosamente muestra el resultado correcto cuando expresamos la división como una fracción:

Si introducimos exactamente lo mismo que hemos visto en la primera imagen en la Casio fx-570SP X II, una calculadora de gama más alta, nos sigue mostrando el mismo resultado, 1, pero esta vez ella misma añade unos ilustrativos paréntesis que hacen el resultado correcto:

Casio fx 570SP X II

Si seguimos el camino que nos indica, es decir, si añadimos paréntesis, sí obtenemos el resultado esperado, en cualquiera de las dos calculadoras, por ejemplo:

En definitiva, el orden de los operadores conduce a la resolución que se ha descrito inicialmente. Ahora bien, en este tipo de operaciones, estas calculadoras no siguen la jerarquía matemáticamente correcta. De hecho, en el manual de la Casio fx-570SP II encontraremos el caso concreto del uso de paréntesis con omisión del signo de multiplicación, y en el de ambas la jerarquía de las operaciones.

Casio Fx 82ES PLUS operacion correcta

Aquí no hemos omitido el signo de multiplicación

Parece ser que, el acrónimo tan usado en informática: RTFM (Read The Fucking Manual) también aplica a ordenadores tan sencillos como una calculadora.

i elevado a i

Una serie de artículos acerca de la exponenciación con números complejos, que di por finalizada en su tercera entrega, y a los que el lector puede recurrir si no entiende algo de lo que en el presente artículo se explica, voy a ampliarla para el curioso caso de ii, y digo curioso pues el resultado es un número real.

Vimos que la generalización de la exponenciación, ab, sean a y b reales1 o complejos, es:

Exponenciación generalizada

En el presente caso, a = i, y si bien el logaritmo complejo existe, aplicando la fórmula de Euler, podremos obtener la forma exponencial para calcular fácilmente ii. En primer lugar, vamos a expresar i en forma polar para obtener dos datos que necesitaremos: el módulo y el argumento. El módulo, obviamente, será 1 y el argumento será π/2 radianes, pues i forma un ángulo recto con la parte real o eje de las ordenadas:

El número imaginario en el plano cartesiano complejo

Por lo tanto, i = 1π/2 en polar, mientras que en binómica es (0 +1i). De esta última, gracias a que conocemos tanto el módulo como el argumento, podemos pasar a la trigonométrica:

Expresión que se deduce por trigonometría:

forma trigonometrica del número complejo

Gracias a la fórmula de Euler donde x es el argumento:

Formula de EulerPodemos convertir, finalmente, la unidad imaginaria a la forma exponencial:

Por lo que:

Como i = √-1:

Y ya hemos calculado ii.

En rojo el número i y en azul r = ii en el plano complejo.


Si a ∈ ℝ, a > 0

Ecuación de la asíntota oblicua

Es frecuente que a los alumnos se les enseñe que, si una función tiene un asíntota oblicua que viene dada por y = ax + b, los términos a y b se calcularán a partir de dos fórmulas que deben memorizar:

término b

(1)

término a

(2)

Pero, ¿de dónde provienen? Si tenemos poca memoria y/o preferimos entender el porqué de las cosas, algo bastante conveniente en matemáticas, debemos tener en cuenta que, para una x infinitamente grande, por las propiedades de los límites, se cumplirá f(x) – y = 0:

ecuación asintota oblicua

(3)

Estas propiedades son debidas a que los límites cumplen con las condiciones de linealidad, vamos a aplicarlas paso a paso para ver cómo se obtiene el término b:

obtencion termino bAhora sólo resta aislarlo y obtendremos la fórmula inicial (1). En la ecuación (3), y dado que b no depende de x, podemos aislar a y obtendremos la fórmula (2).

 

Funciones

En azul la función f(x) = x²/(x+1) En rojo su asíntota oblicua y = x – 1

Cambiando un poco de tema, pero no demasiado, puede verse que si a = 0, entonces se trata de una asíntota horizontal, por lo que podemos ver las asíntotas horizontales como un caso particular de las oblicuas.

La Inteligencia Artificial como último legado del ser humano

En este artículo divago, sin pretensión, sobre diferentes temas que me han interesado a lo largo de la vida: la finitud de la misma (tanto la individual como la del conjunto de los seres de este planeta), las distancias insalvables del espacio y su hostilidad a la vida, el sentido de esta… y la informática. Desde luego, el ser humano es algo más que inteligencia, así como para la vida la inteligencia es sólo una herramienta más, como las garras y los dientes o la capacidad de ver de noche, pero a largo plazo, tal vez sea lo único que podamos hacer perdurar.

El planeta tierra no podrá sustentar indefinidamente la vida, especialmente las formas de vida más complejas, como la nuestra, que son también las más delicadas: tenemos mucha menos resistencia que, por ejemplo, las cucarachas, y estás a su vez se quedan cortas frente a determinadas bacterias y virus, algunos capaces de permanecer latentes durante siglos antes de volver a despertar. Ahora mismo, nuestra civilización se enfrenta a dos grandes problemas:

Incluso si superamos estos problemas, obviamente llegarán otros en el futuro que ahora mismo no nos podemos ni imaginar, no tienen porqué ser un virus o un meteorito. Si, finalmente superamos los retos actuales y los futuros, la expansión del sol en su evolución a gigante roja, arrasará el planeta Tierra: su ecuador coincidirá con la órbita actual de Marte.

En ninguno de los otros planetas del sistema solar la vida es posible. Una cosa es poder plantar una bandera gracias a una costosísima misión espacial, otra muy distinta habitar o hacer habitables planetas con temperaturas inhabilitantes, atmósferas con presiones que oscilan entre mortalmente tenue o excesiva, o compuestas por ácido sulfúrico, como es el caso de Venus, el planeta más cercano a la Tierra.

Si miramos más allá del sistema solar nos encontramos que las estrellas más cercanas están a años luz. Además, gracias a la teoría de la relatividad de Albert Einstein, sabemos no tan sólo que la velocidad de la luz no es superable, sino que simplemente no es alcanzable, pues un cuerpo que viajase a dicha velocidad tendría una masa infinita, algo que no es posible. En consecuencia, no creo que el hombre viaje jamás a las estrellas.

Enterprise

El capitán Kirk cumple el requisito indispensable para conocer el Hiperespacio: ser un personaje de ficción.

Nunca hemos percibido ninguna señal de vida fuera de nuestro planeta, por lo que parece razonable suponer que la vida es un rarísimo y especial fenómeno del que sólo tenemos constancia aquí, en esta esfera azul rodeada de un inmenso vacío. Cuando la vida deje de ser posible, nada quedará de ella, ningún rastro ni recuerdo. La única especie que tiene capacidad de cambiarlo es la nuestra, aunque como hemos visto, la realidad del universo juega en nuestra contra para cambiar el destino que le espera a la vida que alberga la Tierra.

Vida: la materia más singular en el cosmos

Vida: la materia más singular en el cosmos.

Ahora bien, los continuos avances que están habiendo en inteligencia artificial podrían, si se mantiene esta evolución a buen ritmo durante décadas, desembocar en un ente capaz de pensar y con conciencia, contenido en microchips si se sigue la evolución de las últimas décadas, o en otros dispositivos futuros que puedan derivar de la computación cuántica u otras alternativas al ordenador actual que puedan surgir en el futuro. Desde luego, teniendo en cuenta el estado actual de la inteligencia artificial y del Machine Learning, es de un gran tecno optimismo suponer que podremos crear una inteligencia comparable a la nuestra.

Esta máquina podría hacer un viaje que no tendría las limitaciones del cuerpo humano respecto al tiempo, a la composición de la atmósfera, ni las restricciones de temperatura. Podría, por lo tanto, hacer un viaje espacial imposible para nosotros, en una nave cuyo diseño se libraría de la dificultad de tener que mantener vivos y en condiciones a seres humanos, dificultad a día de hoy insalvable cuando los tiempos son largos. Simplemente, esta inteligencia artificial podría permanecer suspendida durante miles de años y activarse al llegar a su destino.

Estas máquinas, lanzadas a diferentes estrellas con todo nuestro conocimiento, serían el único legado que quedaría de la vida que una vez hubo en la tierra. Quién sabe si de aquí a millones de años, en otros sistemas no demasiado lejanos al nuestro, otras formas de vida se desarrollen hasta el punto de hacerse nuestras mismas preguntas y puedan desarrollar tecnología orientada a resolverlas, capaz de detectar si en este planeta hay vida, sólo que probablemente para entonces ya no lo habrá.

La vida es algo tan excepcional, no digamos ya la vida inteligente, que resulta remota la posibilidad de que coincidamos en el tiempo y en el espacio. La inteligencia artificial podría aumentar las posibilidades. A día de hoy es ciencia ficción, sí, pero no tanto como el Hiperespacio o convertir a Marte en el jardín del Edén.


Actualizado el 15/11/2018:

De momento, parece que la IA ya colabora en la exploración espacial, concretamente en el diseño de un aterrizador más ligero.