miércoles, 25 de marzo de 2020

Programando un comando de estimación en Stata: Mata101.


David M. Drukker, Director Ejecutivo de Econometría.

Introduzco a Mata, el lenguaje de programación matricial que es parte de Stata.
Esta es la décimo primera publicación de la serie Programando un comando de estimación en Stata. Te recomiendo que empieces por el principio.

Conociendo Mata
Mata es un lenguaje de programación matricial que es parte de Stata. El código mata es rápido porque está compilado en código objeto que se ejecuta en una maquina virtual; escriba help m1_how para más detalles.

El camino más sencillo para aprender Mata es usarlo. Comienzo con una sesión interactiva. (Puedes encontrar útil escribirlo también.)

Ejemplo 1: una primera sesión interactiva de Mata




Escribir mata: hace que Stata abra una sesión de Mata. Escribir end termina la sesión de Mata, volviendo así a Stata. El símbolo de punto . indica que Stata está pidiendo algo que hacer. Después de que escribes mata:, el símbolo de dos puntos: es el compilador de Mata que pide algo por hacer.

Escribir X=J(3,4,5) en el símbolo de dos puntos, Mata compila y ejecuta este codigo. J(r,c,v) es la función de Mata que crea una matriz rxc, donde cada uno de sus elemntos es v. La expresión en el lado derecho del operador = se asigna al simbolo del lado izquierdo.

Escribir X por sí mismo provoca que Mata despliegue lo que contiene X, que es una matriz 3x4 de cincos. Las expresiones no asignadas muestran sus resultados. Escriba help m2_exp para obtener detalles sobre las expresiones.

Escribir  w=(1::4) hace que Mata use el operador de rango de columna para crear un vector columna de 4x1 que se asigna a w y que se despliega cuando se escribe w solamente. Escriba help m2_op_range para detalles y una discusión sobe el operadr de rango de filas.

Al escribir v=X*w, Mata asigna el producto matricial de X veces w a v, que posteriormente despliego. Luego, ilustro que ‘ es el operador de transposición. Escriba help m2_exp, marker (remarks7) para obtener una lista de operadores.

Una vez más, escribir end finaliza la sesión de Mata.

En casi todo el trabajo que hago, extraigo submatrices de una matriz.

Ejemplo 2: extrayendo submatrices de una matriz


Utilizo r(seed) para configurar la semilla para el generador de números aleatorios, para después utilizar runiform(r,c) para crear una matriz 4x4 con desviaciones uniformes, la cual, subsecuentemente despliego.

Paso siguiente, utilizo el operador para unir filas, para crear el vector fila v y utilizar el operador para unir columnas \ para crear el vector columna u.        

Escriba help m2_op_join para más detalles.

Al escribir W[u,v] se extrae de W las filas especificadas en el vector u y las columnas especificadas en el vector v.

Con frecuencia extraigo bloques rectangulares definidos por un elemento superior izquierdo y un elemento inferior derecho. Ilustro esta sintaxis escribiendo
W[| 1,1 \ 3,3 |]

En detalle, [| abre una extracción de subíndice de rango, 1,1 es la dirección del elemento superior izquierdo, \ separa el elemento superior izquierdo del elemento inferior derecho, 3,3 es la dirección del elemento inferior derecho y |] cierra una extracción de subíndice de rango. 
Escriba help m2_subscripts para obtener detalles.

Irónicamente, cuando estoy haciendo programación matricial, con frecuencia quiero el operador elemento por elemento en lugar del operador matriz. Prefije a cualquier operador de matriz en Mata con dos puntos (:) para obtener el equivalente elemento por elemento.

Ejemplo 3: operadores de elementos






Extraigo las cuatro filas inferiores de W, almaceno esta matriz en W y visualizo este nuevo W. Luego, creo un vector conformable en fila v, realizo una multiplicación de v por elementos a través de las columnas de W y visualizo el resultado. No puedo escribir v*W porque v 3×1 no es conformable con W 3×3. Pero puedo, y lo hago, escribir v’*W porque v’ es de orden 1×3 y es conforme con W 3×3.

El ejemplo 4 usa un operador lógico por elementos.

Ejemplo 4: operador lógico por elementos



Muestro el resultado de comparar el elemento conformable v con W. Escriba help m2_op_colon para más detalles.

Datos de Stata en Mata

La función Mata st_data() crea una matriz Mata que contiene una copia de los datos del conjunto de datos Stata en la memoria. La función Mata st_view() crea una vista Mata de los datos en el conjunto de datos Stata en la memoria. Las vistas actúan como matrices, pero hay una compensación de espacio-velocidad. Las copias son rápidas a costa de usar el doble de memoria. Las vistas son más lentas, pero usan poca memoria extra.

Copiar los datos de Stata en Mata duplica la memoria utilizada, pero los valores se almacenan en la memoria de Mata. Cada vez que una función Mata solicita un valor de una matriz, lo encuentra de inmediato. Por el contrario, una vista de los datos en Stata apenas aumenta la memoria utilizada, pero los valores están en la memoria de Stata. Cada vez que una función Mata solicita un valor de una vista, encuentra un letrero que le dice dónde se puede obtener ese valor en Stata.

Ejemplo 5: Datos de Stata en Mata

Después de enumerar las primeras tres observaciones sobre seis variables en el conjunto de datos auto, abro Mata, uso st_data() para poner una copia de todas las observaciones en mpg, headroom y trunk en la matriz Mata Y, y uso st_view() para crear la vista Mata X con todas las observaciones en rep78, turn y foreign.

Después de unir las filas Y y X para crear V, muestro las primeras 3 filas de V. Observe que falta la tercera observación en rep78 y que las matrices y vistas de Mata pueden contener valores faltantes.

Cambiar el valor de un elemento en una vista cambia los datos en Stata. Ilustraré este punto reemplazando el elemento (3,1) de la vista X con 7, mostrando las primeras tres filas de la vista y enumerando las primeras tres observaciones en rep78, turn y foreign.

Copiando matrices entre Mata y Stata

La función Mata st_matrix() coloca una copia de una matriz Stata en una matriz Mata, o coloca una copia de una matriz Mata en una matriz Stata. En el ejemplo 6, V = st_matrix("B") coloca una copia de la matriz Stata B en la matriz Mata V.

Ejemplo 6: creando una copia de una matriz Stata en un vector Mata


En el ejemplo 7, st_matrix(“Z”,W) coloca una copia de la matriz Mata W en la matriz Stata Z.

Ejemplo 7: creando una copia de una matriz Mata en un vector Stata


Cadenas de texto

Las matrices Mata pueden ser matrices de cadenas de texto.

En mi trabajo, con frecuencia tengo una lista de variables en un escalar de cadena de texto con la que es más fácil trabajar como un vector de cadena de texto.

Ejemplo 8: convirtiendo una lista de texto a un vector de texto


Utilizo tokens() para crear el vector de texto s2 de la lista de texto s1.

Flujo de control

Mata tiene construcciones para recorrer un bloque de código encerrado entre llaves o solo ejecutarlo si una expresión es verdadera.

Con frecuencia uso la construcción for() para recorrer un bloque de código.


En este ejemplo, configuro i en el valor inicial de 1. El bucle continuará siempre que i sea menor o igual que 3. Cada vez que se ejecuta el bucle, se ejecuta el bloque de código encerrado entre las llaves y 1 se agrega al valor actual de i. El bloque de código muestra el valor de i. El ejemplo 9 ilustra estos puntos.

Ejemplo 9: un bucle for


A veces, quiero ejecutar un bloque de código siempre que una condición sea verdadera, en cuyo caso uso un ciclo while, como en el bloque de código 2 y el ejemplo 10.

Code block 2: while()



Establezco i en 7 y repito el bloque de código entre las llaves mientras que i es mayor que 5. El bloque de código muestra el valor actual de i, luego resta 1 de i.

Ejemplo 10: un bucle while


La construcción if solo ejecuta un bloque de código si una expresión es verdadera. Usualmente uso la construcción if-else que ejecuta un bloque de código si una expresión es verdadera y otro bloque de código si la expresión es falsa.

Ejemplo 11: una construcción if-else


Llamando Mata en una línea

Con frecuencia hago llamadas de una línea a Mata desde Stata. Una llamada de una línea a Mata hace que Stata abra Mata, compile y ejecute la línea de código de Mata, y vuelva a aparecer en Stata.

Ejemplo 12: una línea llama a Mata

En el ejemplo 12, utilizo una línea para llamar a Mata mata: st_matrix(“Q”,I(3)) para colocar una copia de la matriz Mata que retorna la expresión Mata I(3) dentro de la matriz Stata Q. Después de la linea que llama a Mata, estoy de regreso en Stata, así que uso matrix list Q para mostrar que la matriz Stata Q es una copia de la matriz Mata W.

Hecho y sin hacer

Usé una sesión interactiva para presentar a Mata, el lenguaje de programación matricial que forma parte de Stata.

En la siguiente publicación, muestro cómo definir las funciones de Mata.


No hay comentarios.:

Publicar un comentario