Cómo evaluar un meshgrid en una función con numpy

El objetivo de este post es evaluar un meshgrid 2-dimensional XX, YY en una función que acepta como parámetro una matriz X. El truco consiste en combinar XX, YY en una sola matriz.

Numpy permite la evaluación de matrices de forma muy simple. Considere la siguiente función de prueba, la cual permite evaluar una matriz X y graficar una sección de una esfera:

# benchmark.py
from pylab import *

oper_for_rows = 1


def F1(X, f_bias=0, o=0):
    
    # desvio
    Z = X - o
    
    # note que no se debe especificar axis=1 en .sum()
    # ya que cada vector x en X es un vector unidimensional
    result = (Z ** 2).sum(axis=oper_for_rows) + f_bias
    
    return result

Puntos relevantes:

  • La función toma una matriz X con un shape (r, n), donde r es el número de filas y n es el número de dimensiones
  • Para poder graficar, n debe ser igual a 2
  • La función devuelve un vector result con un shape (r, ) , es decir, es un vector fila

Ahora bien, para una graficación en 3D se requiere generalmente el uso de un meshgrid, el cual es básicamente un ‘plano cartesiano’ definido por dos vectores x, y. Por ejemplo, si deseas un plano coordenado (i.e. meshgrid) en donde el eje x vaya de [0, 4] y el eje y vaya de [0, 4], éste se crea de la siguiente manera

x = linspace(0, 4, 5)  # array([ 0.,  1.,  2.,  3.,  4.])
y = linspace(0, 4, 5)  # array([ 0.,  1.,  2.,  3.,  4.])

xx, yy = meshgrid(x, y)

Las matrices xx,yy permiten recrear este plano coordenado. Por ejemplo, si quisieamos obtener el origen del plano, tendríamos que acceder al punto xx[0,0], yy[0,0]

In [86]: xx
Out[86]: 
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.]])

In [87]: yy
Out[87]: 
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.]])

Ahora bien, hasta ahora tenemos dos matrices xx, yy pero la función F1 sólo acepta una. Para poder evaluar el meshgrid hace falta cambiar su forma de la siguiente manera

# conversion del meshgrid
# al final de la conversion se tendra una matriz de (r, 2)
# donde
# 
#  X = xy[:, 0] representa el eje x
#  Y = xy[:, 1] representa el eje y
xy = vstack((xx.flatten(), yy.flatten()))
xy = xy.T

# separacion de los ejes, 
# solo para facilitar la notacion
X = xy[:, 0]
Y = xy[:, 1]

El ejemplo completo:

# benchmark.py

from pylab import *

oper_for_rows = 1


def F1(X, f_bias=0, o=0):
    
    # desvio
    Z = X - o
    
    # note que no se debe especificar axis=1 en .sum()
    # ya que cada vector x en X es un vector unidimensional
    result = (Z ** 2).sum(axis=oper_for_rows) + f_bias
    
    return result
# plotting.py

from pylab import *
from random_generator import RandomGenerator
from mpl_toolkits.mplot3d import Axes3D


def plot3D(name, x, y, z, color='g', marker='o'):
    
    fig = figure(name)
    ax = fig.add_subplot(111, projection='3d')
    
    ax.scatter(x, y, z, c=color, marker=marker)
    
    ax.set_xlabel('$f_1$')
    ax.set_ylabel('$f_2$')
    ax.set_zlabel('$f_3$')
    
    draw()
    show()
# main.py

from pylab import *
from benchmark import *
from plotting import *


if __name__ == "__main__":
    

    # ejes x, y
    # si quieres mas puntos, aumenta el rango
    x = linspace(0, 4, 5)
    y = linspace(0, 4, 5)
    
    # creacion del meshgrid
    xx, yy = meshgrid(x, y)
    
    # conversion del meshgrid
    # al final de la conversion se tendra una matriz de (r, 2)
    # donde
    # 
    #  X = xy[:, 0] representa el eje x
    #  Y = xy[:, 1] representa el eje y
    xy = vstack((xx.flatten(), yy.flatten()))
    xy = xy.T
    
    # separacion de los ejes, 
    # solo para facilitar la notacion
    X = xy[:, 0]
    Y = xy[:, 1]
    
    
    # evaluacion de F1 con el mesgrid transformado
    Z = F1(xy)
    
    # plot en 3D
    plot3D("testing", X, Y, Z, color='g', marker='o')


ejemplo

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s