close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 15 years ago

Closed 15 years ago

#745 closed task (fixed)

BSR: Sintaxis modular de la API ASCII

Reported by: Víctor de Buen Remiro Owned by: Víctor de Buen Remiro
Priority: highest Milestone: BSR Interface
Component: Math Version: 2.0.1
Severity: blocker Keywords:
Cc:

Description (last modified by Víctor de Buen Remiro)

Es preciso hacer que el lenguaje ASCII-BSR sea más modular y eficiente y resolver tres problemas fundamentales:

  1. Por una parte, escribir explícitamente las ecuaciones de nodos observacionales densos y grandes es demasiado lento. (Ver ticket #634)
  2. Por otra parte, los modelos masivos con multitud de nodos requieren demasiados recursos si se intentan cargar monolíticamente. (Ver ticket #628)
  3. Además, la sintaxis actual no incorpora los filtros no lineales por loque los medelos están inclompletos y no pueden ser ejecutados en sesiones TOL ulteriores.

Para resolver estos problemas se plantea un nuevo esquema en el que la idea inicial sería tener tres tipos de módulos o archivos ASCII-BSR:

  1. primary: los módulos primarios son capaces de leer un sólo segmento de regresión (nodo en el argot jerárquico) basándose en código TOL para la construcción de la matriz. Normalmente lo usaremos para nodos densos observacionales pero eso a BSR no le importa en absoluto, pues no sabe qué cosa es observacional ni latente ni nada. En esos módulos sólo cabe pues un nodo, con su declaración de variables lineales y missing, estructura de la varianza (sigma-ARIMA), sus filtros no lineales y sus restricciones de desigualdad internas, es decir, todo aquello que no afecta a ningún otro. Un módulo primario puede funcionar de forma autónoma, por ejemplo cuando queremos simular un nodo observacional por sí mismo, sin tener en cuenta estructuras jerárquicas, a priori, ni nada por el estilo, aunque eso no creo que se dé muy a menudo, pues lo normal es que la menos haya información a priori.
  2. joint: los módulos de mezcla serían los actualmente permitidos, llamados así por su capacidad de mezclar variables de varios segmentos de regresión. Pueden funcionar autónomamente como hasta ahora, definiendo todas las variables y ecuaciones de forma explícita, o bien integrarse dentro de un módulo máster que se encargue de cargar previamente las variables de las que depende.
  3. master: los módulos maestros simplemente incluyen a otros módulos de cualquier tipo, incluidos otros maestros, si se desea tener los modelos estructurados en varios niveles, de forma que en cada nivel cada uno de los sub-master podría ser ejecutado autónomamente.

Con este esquema, o algo por el estilo, además de ganar en claridad y potencia, estaríamos a un paso de poder paralelizar modelos jerárquicos basándose en la estructura de niveles del módulo master. Más adelante sería también muy útil a la hora de añadir nuevos tipos de módulos, como las estructuras jerárquicas y a priori sobre parámetros fuera del bloque lineal principal de la regresión: ARIMA, Missing o no lineales.

Un ejemplo típico de estructura BSR modular para el caso jerárquico sería la siguiente:

  • ./master.bsr: módulo raíz
    • ./obs/master: nodos observacionales y sus relaciones internas. Para cada nodo tiene un submódulo
      • ./node_name/master.bsr:
        • ./primary.bsr: segmento estrictamente observacional. Contiene los bloques lineal, de omitidos, varianza, ARIMA y filtros no lineales, siendo todos ellos opcionales, aunque al menos debe haber uno.
        • ./joint.bsr: componentes no observacionales internas, es decir, prioris, lantentes y restricciones que relacionan exclusivamente a variables del mismo nodo observacional.
  • ./mix/joint.bsr: componentes no observacionales mixtas, es decir, prioris, lantentes y restricciones que relacionan a variables de distintos nodos observacionales.

Estructura del módulo primario

Un módulos primario se definirá del siguiente modo:

  1. En primer lugar se incluye una cláusula que indique el tipo de módulo que se va a definir
    Module.Type = primary;
    
  2. El orden de definición de las variables del bloque lineal, con la misma sintaxis que rige actualmente para el módulo joint, debe coincidir con el orden de las columnas en la matriz de inputs.
  3. El segmento de regresión es único pero se define con la misma sintaxis que en el módulo joint. En ambos casos hay una novedad: la posibilidad de introducir los filtros no lineales si los hay en la propia definición del ruido. La estructura del campo NoiseDistrib será distinta a la actual BSR.NoiseDistrib para que pueda incluir un nuevo campo en el que almacenar los filtros no lineales.
  4. Luego se introducirán la matriz de output y la de input.
  5. Después se introducirán si las hay, las variables de omitidos con una sintaxis simular a la de los módulos joint pero añadiéndoles la información de su ubicación en las matrices de input u output, las cuales deberían tener un valor omitido en la celda correspondiente, cosa que debe por tanto comprobarse.
  6. Por último se añadirán si las hay, las restricciones de desigualdad sobre las variables del bloque lineal.

Obviamente el Import deberá saber que está escribiendo un módulo primario y pedir las matrices en lugar de los coeficientes así como la ubicación de los omitidos.

A continuación se presenta una plantilla de cómo podría quedar el fichero ASCII de un módulo primario.

/////////////////////////////////////////////////////////////////////////////
// Bayesian Sparse Regression
/////////////////////////////////////////////////////////////////////////////

$BEGIN

Module.Type = primary;

Model.Name = "...";
Model.Description = "...";
Session.Name = "...";
Session.Description = "...";
Session.Authors = "...";

/////////////////////////////////////////////////////////////////////////////
// Defining header of Regression Variables
/////////////////////////////////////////////////////////////////////////////

LinearBlk::<node_name>::<variable-name>::Coef <- {+ or -}<initial value or ?>;
...
LinearBlk::<node_name>::<variable-name>::Coef <- {+ or -}<initial value or ?>;

/////////////////////////////////////////////////////////////////////////////
// Defining header of Noise Distribution
/////////////////////////////////////////////////////////////////////////////
<node_name>::Noise [length and optional time info] 
  ~ <distribution>
// Optional defininition of Non Linear Filters
  with non linear flters {'Set of NameBlock's expresion'};
 
/////////////////////////////////////////////////////////////////////////////
// Defining Regression Equations
/////////////////////////////////////////////////////////////////////////////

Output = {'Matrix or VMatrix expresion'};

Input = {'Matrix or VMatrix expresion'};


/////////////////////////////////////////////////////////////////////////////
// Optional defininition of Ouput Missing Variables
/////////////////////////////////////////////////////////////////////////////

MissingBlk::<MIXTURE or node name>::<missing_name> ? at row <row or date index> for output ~ <distribution>;
...
MissingBlk::<MIXTURE or node name>::<missing_name> ? at row <row or date index> for output ~ <distribution>;


/////////////////////////////////////////////////////////////////////////////
// Defining Parameter Constraints
/////////////////////////////////////////////////////////////////////////////
{+|-}<number> {<=|>=} <number>*LinearBlk::<node_name>::<variable-name>::Coef + ... + <number>*LinearBlk::<node_name>::<variable-name>::Coef;
...
{+|-}<number> {<=|>=} <number>*LinearBlk::<node_name>::<variable-name>::Coef + ... + <number>*LinearBlk::<node_name>::<variable-name>::Coef;


/////////////////////////////////////////////////////////////////////////////
// Defining defininition of Input Missing Variables
/////////////////////////////////////////////////////////////////////////////

MissingBlk::<MIXTURE or node name>::<missing_name> ? at row <row_index> for input <variable_name> ~ <distribution>;
...
MissingBlk::<MIXTURE or node name>::<missing_name> ? at row <row_index> for input <variable_name> ~ <distribution>;

$END

Cambios en la estructura del módulo joint

El módulo joint se queda prácticamente como está con estas salvedades:

  1. Es posible, aunque no obligatorio por compatibilidad hacia atrás, especificar el tipo de módulo en la cabecera del archivo:
    Module.Type = joint;
    
  2. En un módulo joint puede aparecer una referencia a una variable que ha sido definida en otro módulo previo. El reconocedor sintáctico permitirá pues que aparezcan en las ecuaciones e inecuaciones variables no definidas. En la estructura BSR.LinearBlock se añade un campo Real Extern cuyo valor será puesto a TRUE en estos casos para que puedan resolverse más tarde las referencias.

Mezcla de módulos en el master

El master debe ocuparse de mezclar los modelos o submodelos resultantes de de los módulos en un solo modelo BSR.
El modo de hacerlo depende del mecanismo de generación que se vaya a seguir, que puede ser de dos formas

Mecanismo de generación monofase

Es el único mecanismo de generación implementado actualmente, en el que todos los segmentos y variables lineales se aúnan en un solo sistema lineal de ecuaciones sparse.

Se indicará al principio del módulo máster mediante la sintaxis

Modular.Schema = monophasic;

En este caso los BSR.ModelDef que resultan de cada módulo se deben agregar en un sólo BSR.ModelDef que defina el modelo completo siguiendo los isguientes pasos con sumo cuidado:

  1. La información documental (campo DocInfo) que prevalece es la del módulo master mientras que la de los sub-módulos simplemente se olvida.
  2. Se obtiene la lista conjunta de variables (campo LinearBlock) del bloque lineal de cada uno de los módulos sin repeticiones.
  3. Se reubican las posiciones de las variables en cada uno de los módulos
    1. Se modifica el número de columnas y las posiciones de las columnas de la matriz X de inputs para hacerlas coincidir con la posición de las variables en la lista global.
    2. Se modifica el número de columnas y las posiciones de las columnas de la matriz A de las inecuaciones para hacerlas coincidir con la posición de las variables en la lista global.
    3. Se modifica el campo Col de los registros BSR.MissingBlock de definición de omitidos del input en cada módulo
    4. Se modifica el número de filas y columnas de las matrices Cov, L y Li de cada registro BSR.NoiseDistrib correspondiente a cada segmento, así como el conjunto de índices EquIdx de las filas a las que correponde.
  4. Se concatenan las filas de las matrices Y[k], X[k], a[k], A[k] de todos los módulos en las correspondientes Y, X, a, A conjuntas.
  5. Se concatenan los conjuntos de omitidos del input (campo InputMissingBlock) y el output (campo OutputMissingBlock)
  6. Se concatenan los conjuntos de segmentos de regresión (campo NoiseDistrib)

Intentar hacer todas estas operaciones mientras se está leyendo un BSR actual es algo extremadamente complicado de implementar, pues algunas cosas aún no existen y otras están a medias, no se conocen algunas dimensiones, etc. Precisamente por esta razón propongo todo este tema de la modularización de la sintaxis de los ficheros ASCII-BSR.

Mecanismo de generación multifase

En este caso cada módulo se generará condicionalmente al resto de módulos, bien secuencialmente, bien en paralelo cuando tal cosa sea posible. Esto no es necesario que se implemente en una primera versión pero se puede ir adelantando algo del diseño. Se indicará al principio del módulo máster mediante la sintaxis

Modular.Schema = sequential;

ó bien

Modular.Schema = parallel;

según sea el caso.

En ambos casos la mezcla de módulos es distinta al caso de generación monofase, pues en realildad no se hace agregación física de los módulos sino que simplemente se enlazarán las dependencias de variables entre ellos para que luego BSR pueda actualizar sus valores en las sucesivas simulaciones condicionadas, de forma similar a como lo ahcía el antiguo HLM, del cual se podrán tomar bastantes ideas.

Plantilla de un módulo master

Aunque cada módulo internamente especifica con la cláusula Module.Type de que tipo de módulo se trata es conveniente repetir esa información en la sentencia de inclusión del módulo hijo en el módulo master para llamar directamente al parser adecuado, ya que en realidad lo que habrá es 3 parsers distintos, el de módulos primarios, el de los joint, que es básicamente el actual y el de los masters. La cláusula Module.Type puede usarse como mecanismo de control para evitar posibles errores de diseño del modelo. Así podría quedar la sintaxis de los módulos master

/////////////////////////////////////////////////////////////////////////////
// Bayesian Sparse Regression
/////////////////////////////////////////////////////////////////////////////

$BEGIN

Module.Type = master;

Model.Name = "...";
Model.Description = "...";
Session.Name = "...";
Session.Description = "...";
Session.Authors = "...";

Modular.Schema = { monophasic, sequential or parallel } ;

Include { primary, joint or master } module "file_relative_path.bsr" ;
...
Include { primary, joint or master } module "file_relative_path.bsr" ;

$END

Change History (21)

comment:1 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:2 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:3 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:4 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:5 Changed 15 years ago by Víctor de Buen Remiro

Status: newaccepted

comment:6 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:7 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:8 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:9 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:10 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:11 Changed 15 years ago by Víctor de Buen Remiro

Resolution: fixed
Status: acceptedclosed

(In [1465]) First version of modular parser
Fixes #745

comment:12 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:13 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:14 Changed 15 years ago by Víctor de Buen Remiro

(In [1470]) First version of modular parser
Fixes #745

comment:15 Changed 15 years ago by Víctor de Buen Remiro

Description: modified (diff)

comment:16 Changed 15 years ago by Víctor de Buen Remiro

Resolution: fixed
Status: closedreopened

Si los módulos primarios admitieran variables externas entonces se podrían usar para definir nodos prior y latentes de uno en uno de una forma más organizada que con los módulos joint. Cuando hay nodos muy grandes o muchos nodos será más eficiente su manejo por separado y permitirá mayor flexibilidad en la paralelización, además de evitar la expresión de las ecuaciones de forma explícita.

comment:17 Changed 15 years ago by Víctor de Buen Remiro

(In [2000]) refs #745

comment:18 Changed 15 years ago by Víctor de Buen Remiro

(In [2001]) refs #745

comment:19 Changed 15 years ago by Víctor de Buen Remiro

(In [2003]) refs #745

comment:20 Changed 15 years ago by Víctor de Buen Remiro

(In [2006]) refs #745

comment:21 Changed 15 years ago by Víctor de Buen Remiro

Resolution: fixed
Status: reopenedclosed
Note: See TracTickets for help on using tickets.