Métodos eficientes basados en SQL para la regresión lineal a gran escala

33
Bayes Inference REGRESIÓN LINEAL MASIVA EN SQL Métodos eficientes basados en SQL para la regresión lineal a gran escala DOCUMENTACIÓN TÉCNICA Víctor de Buen Junio 2003

Transcript of Métodos eficientes basados en SQL para la regresión lineal a gran escala

Bayes Inference

REGRESIÓN LINEAL MASIVA EN

SQL

Métodos eficientes basados en SQL

para la regresión lineal a gran

escala

DOCUMENTACIÓN TÉCNICA

Víctor de Buen

Junio 2003

Bayes Forecast [email protected] http://www.bayesforecast.com/

i

Contenido

1. Introducción ____________________________________________________ 1

2. Modelos lineales en SQL _________________________________________ 2

2.1 Algoritmo de Lanczos de regresión lineal por mínimos cuadrados ________ 2

2.2 Implementación del algoritmo de Lanczos en TOL-SQL ________________ 3

2.3 Rendimiento del algoritmo de Lanczos _____________________________ 4

3. Estimación masiva de modelos lineales con inputs comunes ______________ 5

3.1 Algoritmo de regresión lineal reducida ______________________________ 5

3.2 Implementación de la regresión lineal reducida en TOL-SQL ____________ 7

3.3 Rendimiento de la regresión lineal reducida _________________________ 8

4. ANEXO I : Código TOL ___________________________________________ 1

4.1 Librería DBMatSet _____________________________________________ 1

4.1.1 DBMatSetParam.tol _________________________________________ 1

4.1.2 DBMatSet.tol ______________________________________________ 1

4.1.3 DBMatSetImportExport.tol ____________________________________ 3

4.1.4 DBMatSetAlgebra.tol ________________________________________ 4

4.1.5 DBMatSetLinearModel.tol_____________________________________ 7

4.1.6 DBMatSetReducedLinearModel.tol _____________________________ 9

4.2 Tests de la librería DBMatSet____________________________________ 10

4.2.1 DBMatSetProof01.TOL _____________________________________ 10

4.2.2 DBMatSetProof02.TOL _____________________________________ 11

4.2.3 DBMatSetProof03.TOL _____________________________________ 13

4.2.4 DBMatSetProof04.TOL _____________________________________ 13

4.2.5 DBMatSetProof05.TOL _____________________________________ 14

4.2.6 DBMatSetProof06.TOL _____________________________________ 16

Bayes Forecast http://www.bayesforecast.com/ [email protected]

ii

Resumen

El objetivo de este documento es plantear métodos eficientes de estimación y previsión de un gran número de series temporales interrelacionadas de forma que, en un tiempo relativamente corto, permita desarrollar modelos estadísticos aceptables que expliquen el comportamiento de dichas series, acelerando los procesos de análisis y explotación.

Se plantean dos posibles líneas de mejora que son independientes y compatibles entre sí:

Escribir algoritmos de estimación de modelos en SQL para evitar el coste de tiempo y de espacio de disco y memoria que supone el acceso masivo a grandes bases de datos, tanto para lectura como para escritura.

Aprovechar el hecho de que en los problemas de estimación masiva suele haber un gran número de variables en común a muchos grupos de series.

Bayes Forecast [email protected] http://www.bayesforecast.com/

iii

Copyright 2003, Bayes Inference, S.A.

Entidad REGRESIÓN LINEAL MASIVA EN SQL

Asunto Métodos eficientes basados en SQL para la regresión lineal a gran escala

Archivo regresiónlinealmasivaensql

Edición 2003-06-24 17:51

Claves Estimación, previsión, masivo, análisis multivariante

Distribución General

Bayes Forecast [email protected] http://www.bayesforecast.com/

1

1. Introducción

Cuando se manejan grandes cantidades de series temporales u otro tipo de estructuras almacenadas en bases de datos o datawarehouses, cualquier operación que involucre descargas y actualizaciones externas a la base de datos, implica necesidades ingentes de tiempo y espacio.

El análisis estadístico detallado de una serie de cierta importancia, como el total de ventas de una cadena de supermercados o la tirada de un periodo en una ciudad, es de tal envergadura que el acceso a los datos es sólo una parte ínfima del problema. Pero cuando lo que se quiere analizar es, por ejemplo, las ventas por cada punto de venta, o aún más, las ventas de cada producto en cada punto; el número de datos crece vertiginosamente, al mismo tiempo que disminuye la importancia del nodo analizado.

Entonces se hace necesaria la búsqueda de nuevas técnicas de estimación que impliquen sustanciosas rebajas en el consumo de recursos, para establecer una relación aceptable de coste y beneficio del análisis.

Una posible estrategia consiste en desarrollar métodos de estimación que utilicen exclusivamente las herramientas de la propia base de datos. Si además se desea que la programación sea lo más exportable posible entre diferentes sistemas operativos y bases de datos la opción más sensata es utilizar el SQL estándar, al menos dentro de lo posible.

Puesto que el código SQL carece de las más elementales funcionalidades de programación se ha optado por utilizar TOL como sistema de generación de código SQL parametrizado a las necesidades de cada momento.

Bayes Forecast http://www.bayesforecast.com/ [email protected]

2

2. Modelos lineales en SQL

En primer lugar se expone de forma teórica un método de estimación de regresiones lineales por mínimos cuadrados, y después se presenta el código TOL necesario para su implementación. Finalmente se muestran los resultados prácticos simulados para hacer patente la potencia del método expuesto.

La regresión lineal es el modelo estadístico más sencillo pero no por ello deja de ser útil en multitud de ocasiones, pues bajo las transformaciones pertinentes es capaz de amoldarse a situaciones diversas y resulta de una claridad de exposición indudable.

2.1 Algoritmo de Lanczos de regresión lineal por mínimos

cuadrados

El siguiente método (CGLS) es una variante del gradiente biconjugado basado en la iteración de bidiagonalización de Lanczos

i

Sea el modelo lineal Axb de m datos y n variables, con nm . Cuando se

desea estimar los valores de x se puede utilizar el siguiente algoritmo. Partiendo de

los valores iniciales 0x se calculan

;;;2

20000000 srAspAxbr T

y mediante la siguiente recursión para MaxIterj ,,1,0

jjjjjjjjjj

T

j

jjjjjjjjjjjjj

pspsrAs

qrrpxxqApq

111

2

21111

11

2

2

)8)7)6)5

)4)3)2)1

mientras se cumpla la condición

Tolerancej

Este método converge en un máximo de n iteraciones en aritmética exacta aunque

en la aritmética discreta de las computadoras puede tardar algo más dependiendo del número de condición de la matriz de datos.

De hecho el método converge bajo condiciones de correlación múltiple extrema e incluso bajo singularidad. En cualquier caso siempre es conveniente hacer todo lo posible por evitar la colinealidad, eliminando al menos las situaciones más sencillas, como son las variables nulas y las colineales dos a dos.

Bayes Forecast [email protected] http://www.bayesforecast.com/

3

2.2 Implementación del algoritmo de Lanczos en TOL-SQL

Puesto que el algoritmo anterior sólo requiere las operaciones de suma y producto de matrices y de matrices por escalares, basta con crear las sentencias SQL que implementan dichas operaciones para poder escribir de una forma modular el algoritmo. Las matrices se almacenarán en tablas de la base de datos con la siguiente estructura:

CREATE TABLE ejemplo

(

itemKey int NOT NULL, --// identificador de la matriz

i int NOT NULL, --// fila

j int NOT NULL, --// columna

x float NULL --// valor de la celda

) ON [PRIMARY]

GO

En estas tablas se pueden almacenar conjuntos de matrices de dimensiones cualesquiera y diferentes entre sí, matrices que son identificables por el campo

itemKey. Las celdas para las que no hay registro se consideran de valor cero, para obtener así un método eficaz de almacenamiento y manejo de matrices ralas (sparce matrices).

Se podría sustituir el campo itemKey por cualquier conjunto de campos que constituyan una clave primaria del conjunto de matrices en cada caso particular, aunque esto complicaría la programación y ralentizaría la ejecución. Una alternativa consiste en traducir cada campo de la clave a un entero con un número fijo de cifras y concatenarlos para formar un solo código, del cual se puede extraer cada componente mediante operaciones aritméticas muy sencillas.

La operación suma de matrices se corresponde con la consulta SQL

select itemKey, i, j, Sum(x)

from (

select itemKey, i, j, x from A union all

select itemKey, i, j, x from B

) as aux

group by itemKey, i, j

order by itemKey, i, j

La operación producto de matrices se corresponde con la consulta SQL

select A.itemKey, A.i, B.j, Sum(A.x * B.x) from A, B

where A.itemKey=B.itemKey AND A.j = B.i

group by A.itemKey, A.i, B.j

order by A.itemKey, A.i, B.j

Estos son los ficheros TOL de generación del código SQL necesario.

Fichero Propósito DBMatSetParam.tol Parámetros de acceso a la base de datos

DBMatSet.tol Creación y manejo de conjuntos de matrices en la base de datos mediante código SQL generado por TOL.

DBMatSetAlgebra.tol Operaciones algebraicas básicas de matrices en SQL.

DBMatSetLinearModel.tol Estimación de modelos lineales en SQL.

Bayes Forecast http://www.bayesforecast.com/ [email protected]

4

2.3 Rendimiento del algoritmo de Lanczos

El código anterior ha sido probado bajo el sistema operativo Windows 2000 y la base de datos SQL Server 2000 en un ordenador portátil Aspire 1400XC con procesador Intel Pentium

© 4 a 1.7 GHz, memoria de 512 MB SDRAM, y disco de

20GB Ultra ATA/100 HDD, obteniéndose los siguientes resultados

itemKey i j seconds itemkey*i*j^2 seconds /

(itemkey*i*j^2/10^6)

100 100 5 15.70 250,000 62.80

10 100 20 30.71 400,000 76.79

100 100 10 47.90 1,000,000 47.90

1,000 100 5 171.39 2,500,000 68.55

100 1,000 5 149.36 2,500,000 59.74

100 100 20 174.16 4,000,000 43.54

1,000 100 10 491.00 10,000,000 49.10

1,000 100 20 2,473.97 40,000,000 61.85

100 1,000 20 1,956.42 40,000,000 48.91

seconds / (itemkey*i*j^2/10^6)

0.00

10.00

20.00

30.00

40.00

50.00

60.00

70.00

80.00

90.00

100,000 1,000,000 10,000,000 100,000,000

El tiempo de proceso es aproximadamente proporcional al producto del número de matrices (itemKey) por el tamaño muestral (i) por el cuadrado del número de variables (j), tal y como era de esperar según la complejidad del problema de resolución de sistemas lineales por métodos derivados del gradiente conjugado.

Bayes Forecast [email protected] http://www.bayesforecast.com/

5

3. Estimación masiva de modelos lineales con inputs

comunes

Cuando tenemos una gran cantidad de modelos lineales para los que existe un grupo de inputs comunes a todos ellos, se pueden estimar de una forma mucho más eficiente a través de la descomposición de valor singular de la matriz correspondiente a dichos inputs comunes.

3.1 Algoritmo de regresión lineal reducida

Sea el modelo lineal

nnmnnmXXeYeXXY nmnmnnm

;0,,;;;;;,

en el que se conoce la descomposición de valor singular de X

diagonalesy DIVVIUUVDUUDVX n

T

n

TnnnmT ;;,;

(SVD: Singular Value Decomposition. Ver el documento ii)

Si X es de rango completo, nXr entonces nVrDrUr , y la matriz

pseudoinversa de X es

nXrUVDX T 1

y cumple que

nnTTT VVUDVUVDXX 1

Como TVV es idempotente y regular puesto que

nVrVVr

VVVVVVVV

T

TTTT

2

Se tiene que n

T IVVXX

Por otro lado, TUU también es idempotente, pero en este caso se trata de una

matriz a todas luces singular, luego

m

T

T

mmTTT

IUUXXmnUUr

UUUVDUDVXX

1

Volviendo al modelo inicial

eXXY

Bayes Forecast http://www.bayesforecast.com/ [email protected]

6

y premultiplicando por X

eXXXXXYX

Como nIXX , se puede expresar en función de

eXYX

eXXXYX

y sustituir en el modelo

eUUIXUUIYUUI

eXeXYUUY

eXeXYXXY

T

m

T

m

T

m

T

Como ya se ha visto que 0 T

m UUI , se puede estimar con la regresión lineal

eUUIeXUUIXYUUIYeXY T

m

T

m

T

m ****** ;;

y después calcular teniendo en cuenta que su esperanza es

XYXEeXYXEE

Por último, se calculan los residuos del modelo

XXYe

En cuanto a los pre-productos por la matriz TUUI se deben implementar del

siguiente modo

0; wWWUUWWUUI wmTT

pues de esta manera se evita la el coste de espacio de memoria necesario para manejar la matriz

mmTUUI es 2mO

que puede ser muy grande teniendo en cuenta que m puede medirse en cientos,

miles, o decenas de miles.

Otro método de cálculo de la pseudoinversa es

TT XXXX1

que sí se podría desarrollar en SQL y conlleva menos coste de cálculo, pero que es

numéricamente mucho menos estable, por estar la matriz XX T necesariamente peor condicionada que X .

Bayes Forecast [email protected] http://www.bayesforecast.com/

7

3.2 Implementación de la regresión lineal reducida en TOL-

SQL

El algoritmo de la descomposición de valor singular (SVD: Singular Value Decomposition) es demasiado complejo como para implementarlo en SQL. En cualquier caso el número de datos necesarios es mucho menor por tratarse de una sola matriz para cada grupo de modelos con una parte importante de inputs en común.

Por ello se puede importar la matriz y desarrollar los cálculos en TOL para después guardar la descomposición en la base de datos y continuar el cálculo en SQL.

El pre-producto por las matrices U y TU involucrados en los pre-productos por la

matriz TUUI que es fija para cada grupo por matrices distintas, requiere algunas

modificaciones de las consultas SQL.

La operación producto de matrices estándar en SQL

select A.itemKey, A.i, B.j, Sum(A.x * B.x) from A, B

where A.itemKey=B.itemKey AND A.j = B.i

group by A.itemKey, A.i, B.j

order by A.itemKey, A.i, B.j

pasaría a ser, por ejemplo,

select B.itemKey, A.i, B.j, Sum(A.x * B.x) from A, B

where A.itemKey = cast(B.itemKey/10000 as int) AND A.j = B.i

group by B.itemKey, A.i, B.j

order by B.itemKey, A.i, B.j

si se han definido los grupos de modelos con inputs comunes mediante las cifras de itemKey anteriores a la cuarta por el final. Lo importante es que la relación de grupo

se establezca mediante operaciones aritméticas sencillas sobre el campo itemKey, tal y como ya se ha dicho.

Fichero Propósito DBMatSetImportExport.tol Funciones de importación y exportación de conjuntos de

matrices entre TOL y la base de datos. Estas funciones son útiles para la simulación y comprobación de resultados con conjuntos pequeños y medianos de matrices.

DBMatSetReducedLinearModel.tol Implementa las funciones de generación de código SQL para la estimación reducida de modelos lineales agrupados en modelos que tienen una parte importante de inputs en común.

Bayes Forecast http://www.bayesforecast.com/ [email protected]

8

3.3 Rendimiento de la regresión lineal reducida

Puesto que la complejidad de la regresión lineal crece cuadráticamente con el número de variables, la reducción de cálculo puede ser muy importante cuando se estiman muchos modelos como el anterior siendo la matriz X común a todos ellos y el resto distinto en cada uno. Si el número de modelos es K , la complejidad pasa de

2nnmKO a 2nnmKO

Si la proporción de variables comunes es y el total de variables es nnN , el

ahorro porcentual en el tiempo de cálculo será

221111

1 222

2

22

NNN

NNN

En los siguientes gráficos se observa el ahorro porcentual que se puede conseguir para diferentes proporciones de variables en común, en especial para proporciones altas (por encima del 90%).

Bayes Forecast [email protected] http://www.bayesforecast.com/

1

4. ANEXO I : Código TOL

4.1 Librería DBMatSet

A continuación se presentan los ficheros con el código TOL generador de SQL que implementa los algoritmos expuestos anteriormente.

4.1.1 _initDBMatSet.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : _initDBMatSet.TOL

// PURPOSE : Carga todos los ficheros de la librería DBMatSet en el orden

// adecuado

//////////////////////////////////////////////////////////////////////////////

Set Include("DBMatSetParam.tol");

Set Include("DBMatSet.tol");

Set Include("DBMatSetImportExport.tol");

Set Include("DBMatSetAlgebra.tol");

Set Include("DBMatSetLinearModel.tol");

Set Include("DBMatSetReducedLinearModel.tol");

/* FIN DEL FICHERO _initDBMatSet.tol */

4.1.2 DBMatSetParam.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetParam.TOL

// PURPOSE : Parámetros de acceso a la base de datos.

// Se debe crear una base de datos de prueba de nombre

// MatrixAlgebra, o bien, si se quiere usar una base de datos

// existente, cambiar el valor de DBMatSetDatabase.

//////////////////////////////////////////////////////////////////////////////

Text DBMatSetHost = "Santalo";

Text DBMatSetDatabase = "MatrixAlgebra";

Text DBMatSetUser = "";

Text DBMatSetPassword = "";

/* FIN DEL FICHERO DBMatSetParam.tol */

4.1.3 DBMatSet.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSet.tol

//

// PURPOSE : Funciones de creación y manejo de conjuntos de matrices en la

// base de datos mediante código SQL generado por TOL.

//

// Algunas partes de este código sólo funcionan para SQL Server por

// lo que pueden ser necesarios ciertos cambios para otras bases de

// datos.

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetOpen(Real unused)

//////////////////////////////////////////////////////////////////////////////

{

DBOpen(DBMatSetDatabase,DBMatSetUser,DBMatSetPassword)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetClose(Real unused)

//////////////////////////////////////////////////////////////////////////////

{

DBClose(DBMatSetDatabase)

};

//////////////////////////////////////////////////////////////////////////////

Real DBWriteQueries = Copy(FALSE);

Real DBWExecQuery(Text q)

// PURPOSE: Escribe el código de una query, la ejecuta y escribe el resultado.

// Si DBWriteQueries está definida como FALSE sólo la ejecuta.

//////////////////////////////////////////////////////////////////////////////

{

If(DBWriteQueries,WriteLn("

//////////////////////////////////////////////////////////////////////////////

// RUNNING QUERY

//////////////////////////////////////////////////////////////////////////////

"));

If(DBWriteQueries,WriteLn(q+"\n Time : "+Time));

Real ex = DBExecQuery(q);

If(DBWriteQueries,WriteLn("\n RESULT = "<<ex+" Time : "+Time+"\n"));

ex

};

//////////////////////////////////////////////////////////////////////////////

Real DBExistTable(Text tableName)

// PURPOSE : Detección de la existencia de la tabla (SQL Server)

Bayes Forecast http://www.bayesforecast.com/ [email protected]

2

//////////////////////////////////////////////////////////////////////////////

{

DBTable("

select count(*)

from dbo.sysobjects

where

id = object_id(N'[dbo].["+tableName+"]') and

OBJECTPROPERTY(id, N'IsUserTable') = 1

")[1][1]

};

//////////////////////////////////////////////////////////////////////////////

Text DBMatSetDeleteOrDropMethod = "Drop";//"Delete";

Real DBMatSetCreateTable(Text tableName)

// PURPOSE: Genera una tabla capaz de almacenar matrices de forma masiva.

// Cada fila representa una celda y contiene el campo <itemKey>

// que representa a la matriz, el campo <i> para la fila, el campo

// <j> para la columna, y el campo <x> para el valor de la celda.

// Los tres primeros son clave primaria del conjunto de celdas.

//

// Se podría sustituir el campo <itemKey> por cualquier conjunto de

// de campos que constituyan una clave primaria del conjunto de

// matrices en cada caso particular aunque esto complicaría la

// programación y ralentizaría la ejecución.

//

// Una alternativa consiste en traducir cada campo de la clave a un

// número con un número fijo de cifras y concatenarlos para formar

// un sólo número del cual se puede extraer cada componente mediante

// operaciones aritméticas muy sencillas.

//

// Si la tabla ya existe primero la borra o la vacía según el valor

// de DBDeleteOrDropMethod sea "Drop" o "Delete" respectivamente.

//////////////////////////////////////////////////////////////////////////////

{

Real found = DBExistTable(tableName);

//Borrado o vaciado de la tabla existente

If(!found, 0,

If(DBMatSetDeleteOrDropMethod =="Drop",

DBWExecQuery("drop table "+tableName+";"),

DBWExecQuery("delete "+tableName+";") ));

//Creación de la tabla si es necesario

If(And(found,DBMatSetDeleteOrDropMethod!="Drop"), 0, DBWExecQuery("

CREATE TABLE "+tableName+"

(

[itemKey] [int] NOT NULL,

[i] [int] NOT NULL,

[j] [int] NOT NULL,

[x] [float] NULL

) ON [PRIMARY];

"))

};

//////////////////////////////////////////////////////////////////////////////

//Real DBMatSetUseIndex = Copy(FALSE);

Real DBMatSetUseIndex = Copy(TRUE);

Real DBMatSetCreateIndex(Text tableName)

// PURPOSE: Crea el índice de clave primaria <itemKey>,<i>,<j> y uno auxiliar

sobre <itemKey>

//////////////////////////////////////////////////////////////////////////////

{

If(!DBMatSetUseIndex,0,

{

DBWExecQuery("CREATE UNIQUE INDEX PK_"+tableName+" ON

"+tableName+"(itemKey,i,j);");

DBWExecQuery("CREATE INDEX K1_"+tableName+" ON "+tableName+"(itemKey);");

1

})

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetDrop(Text A)

// PURPOSE: Borra la tabla A de la base de datos en curso

//////////////////////////////////////////////////////////////////////////////

{

DBWExecQuery("drop table "+A+";")

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetCopy(Text C, Text A)

// PURPOSE: Crea una nueva tabla C igual a A

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select itemKey, i, j, x

from "+A+"

order by itemKey, i, j

");

DBMatSetCreateIndex(C)

};

/* FIN DEL FICHERO DBMatSet.tol */

Bayes Forecast [email protected] http://www.bayesforecast.com/

3

4.1.4 DBMatSetImportExport.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetImportExport.TOL

// PURPOSE : Funciones de importación y exportación de conjuntos de matrices

// entre TOL y la base de datos.

// Estas funciones son últiles para la simulación y comprobación de

// resultados con conjuntos pequeños y medianos de matrices.

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetSaveFile(Text tableName, Set s)

// PURPOSE: Guarda un conjunto s de matrices como una tabla en la base de

// datos abierta, cuyo nombre se ha especificado en tableName

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(tableName);

//matrix ns = BinGroup("<<",For(1,Card(s), Matrix(Real k)

Set ns = For(1,Card(s), Matrix(Real k)

{

Real r = Rows (s[k][2]);

Real c = Columns(s[k][2]);

Matrix itemKey = Rand(r,1,s[k][1],s[k][1]);

Matrix i = Tra(SetMat([[ Range(1,r,1) ]]));

BinGroup("<<", For(1, c, Matrix(Real j)

{

Matrix cj = Rand(r,1,j,j);

itemKey | i | cj | SubCol(s[k][2],[[j]])

}))

});

Text bcp = "DBAUX_"+tableName+".bcp";

Set BMTFile(ns, bcp);

Text path = ".";

//Replace(GetFilePath(GetAbsolutePath(bcp)),"/","\\")+"\\db_buffer";

Text WriteFile("DBAUX_"+tableName+".fmt",

"8.0\n"+

"5\n"+

"1 SQLCHAR 0 30 \";\" 1 itemKey Modern_Spanish_CI_AS \n"+

"2 SQLCHAR 0 30 \";\" 2 i Modern_Spanish_CI_AS \n"+

"3 SQLCHAR 0 30 \";\" 3 j Modern_Spanish_CI_AS \n"+

"4 SQLCHAR 0 30 \";\" 4 x Modern_Spanish_CI_AS \n"+

"5 SQLCHAR 0 30 \"\\r\\n\" 5 unused Modern_Spanish_CI_AS \n");

Real found = DBExistTable(tableName+"_TXT");

If(And(found,DBMatSetDeleteOrDropMethod=="Drop"), DBWExecQuery("

DROP TABLE "+tableName+"_TXT;"));

Real If(And(found,DBMatSetDeleteOrDropMethod!="Drop"), 0, DBWExecQuery("

CREATE TABLE "+tableName+"_TXT

(

[itemKey] [char] (32) NOT NULL,

[i] [char] (32) NOT NULL,

[j] [char] (32) NOT NULL,

[x] [char] (32) NULL,

[unused] [char] (32) NULL

) ON [PRIMARY];

"));

Text order = "bcp "+DBMatSetDatabase +".."+tableName+"_TXT "+

" in "+path+"\\DBAUX_"+tableName+".bcp"+

" -f "+path+"\\DBAUX_"+tableName+".fmt"+

" -o "+path+"\\DBAUX_"+tableName+".log"+

" -e "+path+"\\DBAUX_"+tableName+".err"+

" -T -S "+DBMatSetHost;

WriteLn(order);

Real System(order);

Real DBWExecQuery("

insert into "+tableName+"

select itemKey, i, j, x

from "+tableName+"_TXT;");

Real DBWExecQuery("DROP TABLE "+tableName+"_TXT;");

Real FileDelete("DBAUX_"+tableName+".bcp");

Real FileDelete("DBAUX_"+tableName+".fmt");

Real FileDelete("DBAUX_"+tableName+".log");

Real FileDelete("DBAUX_"+tableName+".err");

WriteLn(bcp);

1

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetSaveInsert(Text tableName, Set s)

// PURPOSE: Guarda un conjunto s de matrices como una tabla en la base de

// datos abierta, cuyo nombre se ha especificado en tableName

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(tableName);

Real n = SetSum(For(1,Card(s), Real(Real k)

{

Text S = IntText(s[k][1]);

WriteLn("Saving "+tableName+"["+S+"] Time : "+Time);

Set IJ = CartProd(Range(1,Rows(s[k][2]),1),Range(1,Columns(s[k][2]),1));

Real n = Card(IJ);

Set tr = Range(1,n,500);

Real SetSum(For(1,Card(tr)-1,Real(Real t)

{

Real isEmpty = 1;

Text query = "INSERT INTO "+tableName+" "+

SetSum(For(tr[t],Min(Card(IJ),tr[t+1]), Text(Real h)

{

Bayes Forecast http://www.bayesforecast.com/ [email protected]

4

Set ij = IJ[h];

Real x = MatDat(s[k][2],ij[1],ij[2]);

Text ins = If(x==0,"",

"select "+S+","+IntText(ij[1])+","+IntText(ij[2])+

","<<x+" from dual");

Text txt = If(And(x,!isEmpty),"\n union all "+ins,ins);

Real If(x!=0, isEmpty := 0);

txt

}))+";";

DBWExecQuery(query)

}))

}));

Copy(n)

};

//////////////////////////////////////////////////////////////////////////////

Set DBMatSetLoad(Text tableName)

// PURPOSE: Devuelve el conjunto de matrices guradadas en una tabla de la base

// de datos abierta, cuyo nombre se ha especificado en tableName

//////////////////////////////////////////////////////////////////////////////

{

Text q1 = "

select itemKey, max(i), max(j)

from "+tableName+"

group by itemKey

order by itemKey

";

//WriteLn(q1);

Set itemKey = DBTable(q1);

Set EvalSet(itemKey,Set(Set s)

{

Text S = IntText(s[1]);

Text q2 = "

select

"+SetSum(For(1,s[3],Text(Real j)

{

Text J = IntText(j);

If(j>1,",\n","")+

" sum(case when j="+J+" then x else 0.0 end) as x"+J

}))+"

from "+tableName+"

where itemkey="+S+"

group by i

order by i

";

WriteLn(q2);

[[ s[1], Matrix DBMatrix(q2) ]]

})

};

/* FIN DEL FICHERO DBMatSetImportExport.tol */

4.1.5 DBMatSetAlgebra.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetAlgebra.tol

//

// PURPOSE : Implementa las funciones de generación de código SQL para las

// operaciones algebraicas básicas de matrices.

// En todas estas funciones no se comprueba previamente que las

// dimensiones de las matrices sean las adecuadas para realizar la

// operación pues ésto ralentizaría demasiado la ejecución.

// No obstante se podría incluir un código de comprobación opcional

// en tiempo de depuración que se pospone de momento.

//

// DEPENDS : DBMatSet.tol

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetSum(Text C, Text A, Text B)

// PURPOSE: Implementa la operación suma masiva de matrices

// C(itemKey,i,j) = A(itemKey,i,j) + B(itemKey,i,j)

//////////////////////////////////////////////////////////////////////////////

{

/*

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, A.j, A.x + B.x

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey AND

A.i=B.i AND

A.j=B.j

order by A.itemKey, A.i, A.j

");

DBMatSetCreateIndex(C)

*/

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select itemKey, i, j, Sum(x)

from

(

select itemKey, i, j, x from "+A+" union all

select itemKey, i, j, x from "+B+"

) as aux

group by itemKey, i, j

order by itemKey, i, j

");

DBMatSetCreateIndex(C)

};

Bayes Forecast [email protected] http://www.bayesforecast.com/

5

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetSubstract(Text C, Text A, Text B)

// PURPOSE: Implementa la operación resta masiva de matrices

// C(itemKey,i,j) = A(itemKey,i,j) - B(itemKey,i,j)

//////////////////////////////////////////////////////////////////////////////

{

/*

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, A.j, A.x - B.x

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey AND

A.i=B.i AND

A.j=B.j

order by A.itemKey, A.i, A.j

");

DBMatSetCreateIndex(C)

*/

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select itemKey, i, j, Sum(x)

from

(

select itemKey, i, j, x from "+A+" union all

select itemKey, i, j, -x from "+B+"

) as aux

group by itemKey, i, j

order by itemKey, i, j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetProduct(Text C, Text A, Text B)

// PURPOSE: Implementa la operación producto masivo de matrices

// C(itemKey,i,j) = Sum(A(itemKey,i,k)*B(itemKey,k,j))

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, B.j, Sum(A.x * B.x)

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey AND

A.j = B.i

group by A.itemKey, A.i, B.j

order by A.itemKey, A.i, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetTrasposedProduct(Text C, Text A, Text B)

// PURPOSE: Implementa la operación producto traspuesto masivo de matrices

// C(itemKey,i,j) = Sum(A(itemKey,k,i)*B(itemKey,k,j))

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.j, B.j, Sum(A.x * B.x)

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey AND

A.i = B.i

group by A.itemKey, A.j, B.j

order by A.itemKey, A.j, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetTrasposed2Product(Text C, Text A, Text B)

// PURPOSE: Implementa la operación producto traspuesto masivo de matrices

// C(itemKey,i,j) = Sum(A(itemKey,i,k)*B(itemKey,j,k))

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, B.i, Sum(A.x * B.x)

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey AND

A.j = B.j

group by A.itemKey, A.i, B.i

order by A.itemKey, A.i, B.i

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetExternProduct(Text C, Text A, Text B)

// PURPOSE: Implementa la operación producto exterior masivo de matrices

// C(itemKey,i,j) = A(itemKey,i,j)*B(itemKey,i,j)

Bayes Forecast http://www.bayesforecast.com/ [email protected]

6

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, B.j, A.x * B.x

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey and

A.i=B.i and A.j=B.j

order by A.itemKey, A.i, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetExternQuotient(Text C, Text A, Text B)

// PURPOSE: Implementa la operación cociente exterior masivo de matrices

// C(itemKey,i,j) = A(itemKey,i,j)/B(itemKey,i,j)

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, B.j, A.x / B.x

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey and

A.i=B.i and A.j=B.j

order by A.itemKey, A.i, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetProduct11(Text C, Text A, Text B)

// PURPOSE: Implementa la operación producto masivo de matriz y escalar

// dependiente de la matriz

//

// C(itemKey,i,j) = A(itemKey,i,j)*B(itemKey,1,1)

//

// NOTA: B contiene matrices de una fila y una columna, es decir,

// escalares

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, B.j, A.x * B.x

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey and

B.i=1 and B.j=1

order by A.itemKey, A.i, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetQuotient11(Text C, Text A, Text B)

// PURPOSE: Implementa la operación cociente masivo de matriz y escalar

// dependiente de la matriz

//

// C(itemKey,i,j) = A(itemKey,i,j)/B(itemKey,1,1)

//

// NOTA: B contiene matrices de una fila y una columna, es decir,

// escalares

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select A.itemKey, A.i, B.j, A.x / B.x

from "+A+" as A, "+B+" as B

where

A.itemKey=B.itemKey and

B.i=1 and B.j=1

order by A.itemKey, A.i, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetSumR(Text C, Text A, Real b)

// PURPOSE: Implementa la operación suma masiva de matrices y escalar fijo

// C(itemKey,i,j) = A(itemKey,i,j) + b

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select itemKey, i, j, x + ("<<b+")

from "+A+"

order by itemKey, i, j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetProdR(Text C, Text A, Real b)

Bayes Forecast [email protected] http://www.bayesforecast.com/

7

// PURPOSE: Implementa la operación producto masivo de matrices y escalar fijo

// C(itemKey,i,j) = A(itemKey,i,j) * b

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select itemKey, i, j, x * ("<<b+")

from "+A+"

order by itemKey, i, j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetPowerR(Text C, Text A, Real b)

// PURPOSE: Implementa la operación producto masivo de matrices y escalar fijo

// C(itemKey,i,j) = A(itemKey,i,j) * b

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select itemKey, i, j, power(x,("<<b+"))

from "+A+"

order by itemKey, i, j

");

DBMatSetCreateIndex(C)

};

/* FIN DEL FICHERO DBMatSetAlgebra.tol */

4.1.6 DBMatSetLinearModel.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetLinearModel.tol

//

// PURPOSE : Implementa las funciones de generación de código SQL para la

// estimación de modelos lineales.

//

// DEPENDS : DBMatSetAlgebra.tol

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetInitialSolution(Text x, Text A, Text b)

// PURPOSE: Devuelve una solución inicial del conjunto de sistemas lineales

//

// Min{||b-Ax||}

// x

//

// que corresponde a la solución del problema cuando las variables

// son independientes.

//////////////////////////////////////////////////////////////////////////////

{

WriteLn("Running Initial Solution for SQL");

DBMatSetTrasposedProduct(x+"_Atb", A, b);

DBMatSetCreateTable(x+"_AtA");

DBWExecQuery("

insert into "+x+"_AtA

select A.itemKey, A.j, 1, Sum(At.x * A.x)

from "+A+" as At, "+A+" as A

where

At.itemKey = A.itemKey AND

At.i = A.i AND

At.j = A.j

group by A.itemKey, A.j

order by A.itemKey, A.j

");

DBMatSetCreateIndex(x+"_AtA");

DBMatSetExternQuotient(x,x+"_Atb",x+"_AtA");

DBMatSetDrop(x+"_Atb");

DBMatSetDrop(x+"_AtA");

1

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetMinResSolve(Text x, Text A, Text b)

// PURPOSE: Resuelve por mínimos cuadrados el conjunto de sistemas lineales

//

// Min{||b-Ax||}

// x

//

// Devuelve el número de iteraciones realizadas.

//////////////////////////////////////////////////////////////////////////////

{

//Función local para la creación de nombres para las tablas auxiliares

Text N(Text sufix) { x+"_"+sufix };

Real t00 = Copy(Time);

DBMatSetCreateTable(x);

WriteLn("Running Minimum Residuals Solve for SQL");

//Dimensionamiento preliminar del problema

Set info = DBTable("

select Count(distinct itemKey), Max(i), Max(j), Count(*)

from "+A+";");

Bayes Forecast http://www.bayesforecast.com/ [email protected]

8

Real items = info[1][1];

Real rows = info[1][2];

Real columns = info[1][3];

Real cells = info[1][4];

WriteLn(Trace(items)+"\n"+Trace(rows)+"\n"+Trace(columns)+"\n"+Trace(cells));

//Iteración inicial de Lanczos

DBMatSetInitialSolution (N("x0"), A, b );

DBMatSetProduct (N("Ax"), A, N("x0"));

DBMatSetSubstract (N("r0"), b, N("Ax"));

DBMatSetTrasposedProduct (N("s"), A, N("r0"));

DBMatSetCopy (N("p"), N("s") );

DBMatSetTrasposedProduct (N("L0"), N("s"), N("s") );

Real j=0;

Real maxL1 = DBTable("select max(x) from "+N("L0")+";")[1][1];

Real maxL0 = maxL1*2;

Real maxAbsDx = 1;

//Ciclo de iteraciones de Lanczos

Real While

(

And

(

LE(j, rows+columns), // Número máximo de iteraciones

GT(maxAbsDx, .1E-7), // Detección de estancamiento de la solución

GT(maxL1, .1E-15) // Detección de estancamiento de la mejora

),

{

t0 = Copy(Time);

Write("\nMRS Iteration "+IntText(j));

DBMatSetProduct (N("q"), A, N("p"));

DBMatSetTrasposedProduct (N("q2"), N("q"), N("q"));

DBMatSetQuotient11 (N("a"), N("L0"), N("q2"));

DBMatSetProduct11 (N("pa"), N("p"), N("a"));

DBMatSetSum (N("x1"), N("x0"), N("pa"));

DBMatSetProduct11 (N("qa"), N("q"), N("a"));

DBMatSetSubstract (N("r1"), N("r0"), N("qa"));

DBMatSetTrasposedProduct (N("s"), A, N("r1"));

DBMatSetTrasposedProduct (N("L1"), N("s"), N("s"));

DBMatSetQuotient11 (N("b"), N("L1"), N("L0"));

DBMatSetProduct11 (N("pb"), N("p"), N("b"));

DBMatSetSum (N("p"), N("s"), N("pb"));

(maxL0 := Copy(maxL1));

(maxL1 := DBTable("select max(x) from "+N("L1")+";")[1][1]);

DBMatSetSubstract (N("Dx"), N("x0"), N("x1"));

(maxAbsDx := DBTable("select max(Abs(x)) from "+N("Dx")+";")[1][1]);

Real prop = DBTable("

select count(*)

from

(

select

itemKey,

Max(Abs(x)) as maxAbsDx

from "+N("Dx")+"

group by itemKey

) as aux

where maxAbsDx > .1E-15;")[1][1];

DBMatSetCopy(N("L0"), N("L1"));

DBMatSetCopy(N("r0"), N("r1"));

DBMatSetCopy(N("x0"), N("x1"));

t1 = Copy(Time);

WriteLn(" prop = " << prop +

" maxAbs(Dx) = " << maxAbsDx +

" maxL0 = " << maxL0 +

" maxL1 = " << maxL1 +

" time = " << Real(t1-t0)+" seconds.");

Real (j := j+1);

j

});

//Se copia la tabla x1 en la especificada por el usuario

DBMatSetCopy(x, N("x1"));

//Por último se borran todas las tablas auxiliares

DBMatSetDrop(N("Dx"));

DBMatSetDrop(N("x0"));

DBMatSetDrop(N("x1"));

DBMatSetDrop(N("Ax"));

DBMatSetDrop(N("r0"));

DBMatSetDrop(N("s" ));

DBMatSetDrop(N("p" ));

DBMatSetDrop(N("L0"));

DBMatSetDrop(N("q" ));

DBMatSetDrop(N("q2"));

DBMatSetDrop(N("a" ));

DBMatSetDrop(N("pa"));

DBMatSetDrop(N("qa"));

DBMatSetDrop(N("r1"));

DBMatSetDrop(N("L1"));

DBMatSetDrop(N("b" ));

DBMatSetDrop(N("pb"));

Real t11 = Copy(Time);

WriteLn("MRS Total time : "<<Real(t11-t00)+" seconds.");

Copy(j)

};

/* FIN DEL FICHERO DBMatSetLinearModel.tol */

Bayes Forecast [email protected] http://www.bayesforecast.com/

9

4.1.7 DBMatSetReducedLinearModel.tol

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetReducedLinearModel.tol

//

// PURPOSE : Implementa las funciones de generación de código SQL para la

// estimación reducida de modelos lineales agrupados en modelos que

// tienen una parte importante de inputs en común.

//

// DEPENDS : DBMatImportExport.tol, DBMatSetLinearModel.tol

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetSVD(Text A)

// PURPOSE: Calcula y guarda las descomposiciones de valor singular de las

// matrices de la tabla A, así como sus matrices pseudoinversas.

// Es necesario que las matrices tengan más filas que columnas.

//////////////////////////////////////////////////////////////////////////////

{

WriteLn(Time+" Running SVD for TOL-SQL ");

Real t0 = Copy(Time);

Set A_ = DBMatSetLoad(A);

Set svdp = Traspose(EvalSet(A_, Set(Set a)

{

Set svd = SVD(a[2]);

Matrix D = svd[2];

Matrix V = svd[3];

[[ [[ a[1], D ]], [[ a[1], V ]]]]

}));

DBMatSetSaveFile (A+"_SVD_D", svdp[1] );

DBWExecQuery("delete from "+A+"_SVD_D where x=0; ");

DBMatSetSaveFile (A+"_SVD_V", svdp[2] );

DBMatSetPowerR (A+"_SVD_Di", A+"_SVD_D", -1);

DBMatSetProduct (A+"_SVD_VDi", A+"_SVD_V", A+"_SVD_Di");

DBMatSetProduct (A+"_SVD_U", A, A+"_SVD_VDi");

DBMatSetTrasposed2Product (A+"_SVD_P", A+"_SVD_VDi", A+"_SVD_U");

DBMatSetDrop (A+"_SVD_VDi");

WriteLn(Time+" End of SVD for TOL-SQL "<<Real(Copy(Time)-t0)+" seconds");

1

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetGroupedProduct(Text C, Text A, Text B,

Text groupCondition)

// PURPOSE: Implementa la operación producto masivo de matrices

// C(itemKey,i,j) = Sum(A(itemKey,Group(i),k)*B(itemKey,k,j))

//

// Por ejemplo la condición

//

// A.itemKey = cast(B.itemKey/10000 as int)

//

// agrupa B por las cifras anteriores

//

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select B.itemKey, A.i, B.j, Sum(A.x * B.x)

from "+A+" as A, "+B+" as B

where

"+groupCondition+" AND

A.j = B.i

group by B.itemKey, A.i, B.j

order by B.itemKey, A.i, B.j

");

DBMatSetCreateIndex(C)

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetGroupedTrasposedProduct(Text C, Text A, Text B,

Text groupCondition)

// PURPOSE: Implementa la operación producto traspuesto masivo de matrices

// C(itemKey,i,j) = Sum(A(itemKey,k,Group(i))*B(itemKey,k,j))

//

// Por ejemplo la condición

//

// A.itemKey = cast(B.itemKey/10000 as int)

//

// agrupa B por las cifras anteriores

//

//////////////////////////////////////////////////////////////////////////////

{

DBMatSetCreateTable(C);

DBWExecQuery("

insert into "+C+"

select B.itemKey, A.j, B.j, Sum(A.x * B.x)

from "+A+" as A, "+B+" as B

where

"+groupCondition+" AND

A.i = B.i

group by B.itemKey, A.j, B.j

order by B.itemKey, A.j, B.j

");

DBMatSetCreateIndex(C)

Bayes Forecast http://www.bayesforecast.com/ [email protected]

10

};

//////////////////////////////////////////////////////////////////////////////

Real DBMatSetReducedMinResSolve(Text x, Text A, Text x_, Text A_, Text b,

Text groupCond)

// PURPOSE: Resuelve por mínimos cuadrados el conjunto de sistemas lineales

//

// b = Ax + A'x' + e

//

// Devuelve el número de iteraciones realizadas.

//////////////////////////////////////////////////////////////////////////////

{

WriteLn(Time+" Running Reduced Minium Residuals Solve for SQL");

Real DBMatSetSVD(A);

Text As = A+"_SVD_";

DBMatSetGroupedTrasposedProduct(As+"Ub", As+"U",b,groupCond);

DBMatSetGroupedProduct (As+"UtUb", As+"U",As+"Ub",groupCond);

DBMatSetDrop (As+"Ub");

DBMatSetSubstract (As+"I_UtUb", b,As+"UtUb");

DBMatSetDrop (As+"UtUb");

DBMatSetGroupedTrasposedProduct(As+"UA_", As+"U",A_,groupCond);

DBMatSetGroupedProduct (As+"UtUA_", As+"U",As+"UA_",groupCond);

DBMatSetDrop (As+"UA_");

DBMatSetSubstract (As+"I_UtUA_", A_,As+"UtUA_");

DBMatSetDrop (As+"UtUA_");

Real iter = DBMatSetMinResSolve(x_, As+"I_UtUA_", As+"I_UtUb");

DBMatSetDrop (As+"I_UtUb");

DBMatSetDrop (As+"I_UtUA_");

DBMatSetProduct (A_+x_, A_, x_);

DBMatSetSubstract (b+A_+x_, b, A_+x_);

DBMatSetDrop (A_+x_);

DBMatSetGroupedProduct (x, As+"P", b+A_+x_,groupCond);

DBMatSetDrop (b+A_+x_);

WriteLn(Time+" Reduced Minium Residuals Solve for SQL "<<

Real(Copy(Time)-t0)+" seconds");

iter

};

/* FIN DEL FICHERO DBMatSetReducedLinearModel.tol */

4.2 Tests de la librería DBMatSet

A continuación se presentan los ficheros de test de funcionamiento de la librería DBMatSet.

4.2.1 DBMatSetProof01.TOL

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetProof01.TOL

// PURPOSE : Prueba por simulación del algoritmo de Lanczos.

// Utiliza las funciones de importación y exportación de DBMatSet

// para guardar en la base de datos las matrices aleatorias

// generadas en TOL necesarias para la prueba del algoritmo de

// Lanczos.

// Las matrices generadas no pueden ser muy grandes, aunque la

// generación pseudoaleatoria de TOL hace muy fiables los resultados

// Úsese para hacer pruebas de precisión numérica.

// Después de compilar este fichero hay que descompilarlo y

// compilar DBMatSetProof03.TOL para completar la prueba.

//////////////////////////////////////////////////////////////////////////////

Set Include("_initDBMatSet.tol");

Real DBMatSetOpen(0);

Real itemKey = 5;

Real i = 100;

Real j = 5;

Set A = For(1,itemKey,Set(Real k)

{

Matrix Ak = Rand(i,j,-2,2);

[[k,Ak]]

});

Set x = For(1,itemKey,Set(Real k)

{

Matrix xk = Rand(j,1,-2,2);

[[k,xk]]

});

Set e = For(1,itemKey,Set(Real k)

{

Bayes Forecast [email protected] http://www.bayesforecast.com/

11

Matrix ek = Gaussian(i,1, 0, .01);

[[k,ek]]

});

Set Ax = For(1,itemKey,Set(Real k)

{

Matrix ek = A[k][2]*x[k][2];

[[k,ek]]

});

Set b = For(1,itemKey,Set(Real k)

{

Matrix ek = A[k][2]*x[k][2]+e[k][2];

[[k,ek]]

});

Real DBMatSetSaveFile("MA_A",A);

Real DBMatSetSaveFile("MA_x",x);

Real DBMatSetSaveFile("MA_e",e);

Real DBMatSetSaveFile("MA_Ax",Ax);

Real DBMatSetSaveFile("MA_b",b);

Set DBMatSetLoad("MA_A");

Real DBMatSetClose(0);

/* FIN DEL FICHERO: DBMatSetProof01.TOL */

4.2.2 DBMatSetProof02.TOL //////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetProof02.TOL

// PURPOSE : Prueba por simulación del algoritmo de Lanczos.

// Utiliza las funciones de importación y exportación de DBMatSet

// para guardar en la base de datos las matrices aleatorias

// generadas en SQL necesarias para la prueba del algoritmo de

// Lanczos.

// Las matrices generadas pueden ser todo lo grandes que admitan

// la computadora y la base de datos, aunque la generación aleatoria

// en SQL no es demasiado fiable.

// Úsese para hacer pruebas de consumo de recursos como tiempo de

// proceso, memoria RAM, memoria virtual, disco, etc.

// Después de compilar este fichero hay que descompilarlo y

// compilar DBMatSetProof03.TOL para completar la prueba.

//////////////////////////////////////////////////////////////////////////////

Set Include("_initDBMatSet.tol");

Real DBMatSetOpen(0);

//////////////////////////////////////////////////////////////////////////////

// Definición de las dimensiones de la simulación:

//

// itemKey : Número de matrices (Volumen de la masividad).

// i : Número de filas por matriz (Tamaño muestral).

// j : Número de columnas por matriz (Número de variables).

//

// OJO: El número total de registros creados es

//

// itemKey*i*j

//

// así que hay que tener cuidado.

//////////////////////////////////////////////////////////////////////////////

Real itemKey = 100;

Real i = 1000;

Real j = 20;

Real dual = If(DBExistTable("dual"),0,

{

DBWExecQuery("CREATE TABLE dual( [unused] [char] NULL) ON [PRIMARY];")

});

Real MA_gen_k = If(DBExistTable("MA_gen_k"),0,

{

WriteLn("Creando la tabla auxiliar MA_gen_k. Time"+Time);

Real DBWExecQuery("

CREATE TABLE MA_gen_k

(

[k] [int] NOT NULL,

[r_itemKey] [float] NOT NULL,

[r_i] [float] NOT NULL,

[r_j] [float] NOT NULL

) ON [PRIMARY];");

Real BlockSize = 1000;

Real MaxBlocks = 10;

WriteLn("Rellenando la tabla auxiliar MA_gen_k con "+

IntText(BlockSize*MaxBlocks)+" registros. Time"+Time);

Set For(0, MaxBlocks-1, Real(Real block)

{

Real k0 = block*BlockSize;

Real DBWExecQuery("insert into MA_gen_k "+

SetSum(For(k0+1,k0+BlockSize, Text(Real k)

{

If(EQ(k,k0+1),"\n ","\n union all ")+

"select

"+IntText(k)+",

Bayes Forecast http://www.bayesforecast.com/ [email protected]

12

"<<Rand(0,1)+",

"<<Rand(0,1)+",

"<<Rand(0,1)+"

from dual"

})));

WriteLn(" "+IntText(k0+BlockSize)+" registros insertados. Time : "+Time);

DBWExecQuery("CREATE UNIQUE INDEX MA_gen_k_PK ON MA_gen_k (k);");

1

});

1

});

//////////////////////////////////////////////////////////////////////////////

Real DBGenSimDimTable(Text D, Real dim)

//////////////////////////////////////////////////////////////////////////////

{

If(!DBExistTable("MA_gen_"+D), 0,

Real DBWExecQuery("drop table MA_gen_"+D+";"));

WriteLn("Creando la tabla auxiliar MA_gen_"+D+". Time"+Time);

Real DBWExecQuery("

CREATE TABLE MA_gen_"+D+"

(

["+D+"] [int] NOT NULL,

[r_"+D+"] [float] NOT NULL

) ON [PRIMARY];");

WriteLn("Rellenando la tabla auxiliar MA_gen_"+D+" con "+IntText(dim)+

" registros. Time"+Time);

Real DBWExecQuery("

insert into MA_gen_"+D+"

select k, r_"+D+" from MA_gen_k

where k<="+IntText(dim)+";");

Real DBWExecQuery("CREATE UNIQUE INDEX PK_MA_gen_"+D+

" ON MA_gen_"+D+" ("+D+");");

1

};

Real MA_gen_itemKey = DBGenSimDimTable("itemKey", itemKey);

Real MA_gen_i = DBGenSimDimTable("i", i);

Real MA_gen_j = DBGenSimDimTable("j", j);

WriteLn("\nGenerating A. Time"+Time);

Real DBMatSetCreateTable("MA_A");

Real DBWExecQuery("

insert into MA_A

select itemKey, i, j, x from (

select

itemKey, i, j,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_i+r_j)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*4 as x

from MA_gen_itemKey, MA_gen_i, MA_gen_j

) as aux;");

WriteLn("\nIndexing A. Time"+Time);

Real DBMatSetCreateIndex("MA_A");

WriteLn("\nGenerating e. Time"+Time);

Real DBMatSetCreateTable("MA_e");

Real DBWExecQuery("

insert into MA_e

select itemKey, i, j, x from (

select

itemKey, i, 1 as j,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_i)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*.01 as x

from MA_gen_itemKey, MA_gen_i

) as aux;");

WriteLn("\nIndexing e. Time"+Time);

Real DBMatSetCreateIndex("MA_e");

WriteLn("\nGenerating x. Time"+Time);

Real DBMatSetCreateTable("MA_x");

Real DBWExecQuery("

insert into MA_x

select itemKey, j, i, x from (

select

itemKey, j, 1 as i,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_j)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*4 as x

from MA_gen_itemKey, MA_gen_j

) as aux;");

WriteLn("\nIndexing x. Time"+Time);

Real DBMatSetCreateIndex("MA_x");

Real DBMatSetTrasposedProduct("MA_test", "MA_e", "MA_e");

Set Table([[ DBTable("select * from MA_test;") ]],"Std");

Real DBWExecQuery("drop table MA_test;");

WriteLn("\nGenerating b. Time"+Time);

Real DBMatSetProduct ("MA_Ax", "MA_A", "MA_x");

Real DBMatSetSum ("MA_b", "MA_Ax", "MA_e");

Real DBMatSetClose(0);

/* FIN DEL FICHERO DBMatSetProof02.tol */

Bayes Forecast [email protected] http://www.bayesforecast.com/

13

4.2.3 DBMatSetProof03.TOL

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetProof03.TOL

// PURPOSE : Prueba por simulación del algoritmo de Lanczos.

// Llama a la función de resolución de sistemas lineales y

// comprueba que el resultado es correcto.

// Antes de ejecutar este fichero es necesario que existan en las

// base de datos las tablas generadas por DBMatSetProof01.TOL o por

// DBMatSetProof02.TOL

//////////////////////////////////////////////////////////////////////////////

Set Include("_initDBMatSet.tol");

Real DBMatSetOpen(0);

Set Table([[ DBTable("

select

itemKey, Sqrt(Avg(x*x)) from MA_e

group by itemkey

order by itemkey;

")]],"Std");

Real DBMatSetMinResSolve ("MA_x_", "MA_A", "MA_b");

Real DBMatSetProduct ("MA_Ax_", "MA_A", "MA_x_");

Real DBMatSetSubstract ("MA_e_", "MA_b", "MA_Ax_");

Real DBMatSetSubstract ("MA_xD", "MA_x", "MA_x_");

WriteLn("\nTest e_");

Set Table([[ DBTable("

select

itemKey, Sqrt(Avg(x*x)) from MA_e_

group by itemkey

order by itemkey;

")]],"Std");

WriteLn("\nTest dif x-x_");

Set Table([[ DBTable("

select

itemKey, max(Abs(x)) from MA_xD

group by itemkey

order by itemkey;

")]],"Std");

Real DBMatSetClose(0);

/* FIN DEL FICHERO: DBMatSetProof03.TOL */

4.2.4 DBMatSetProof04.TOL

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetProof04.TOL

// PURPOSE : Prueba por simulación del algoritmo de estimación lineal

// reducida.

// Utiliza las funciones de importación y exportación de DBMatSet

// para guardar en la base de datos las matrices aleatorias

// generadas en TOL necesarias para la prueba del algoritmo de

// Lanczos.

// Las matrices generadas no pueden ser muy grandes, aunque la

// generación pseudoaleatoria de TOL hace muy fiables los

resultados.

// Úsese para hacer pruebas de precisión numérica.

// Después de compilar este fichero hay que descompilarlo y

// compilar DBMatSetProof03.TOL para completar la prueba.

//////////////////////////////////////////////////////////////////////////////

Set Include("_initDBMatSet.tol");

Real DBMatSetOpen(0);

Real itemKey = 5;

Real g = 1;

Real i = 100;

Real j = 5;

Real jc = 10;

Set A = For(1,itemKey,Set(Real k)

{

Matrix Ak = Rand(i,j,-2,2);

[[k,Ak]]

});

Set x = For(1,itemKey,Set(Real k)

{

Matrix xk = Rand(j,1,-2,2);

[[k,xk]]

});

Set Ax = For(1,itemKey,Set(Real k)

{

Matrix Axk = A[k][2]*x[k][2];

[[k,Axk]]

});

Set Ac = For(1,g,Set(Real k)

{

Matrix Ak = Rand(i,jc,-2,2);

[[k,Ak]]

Bayes Forecast http://www.bayesforecast.com/ [email protected]

14

});

Set xc = For(1,itemKey,Set(Real k)

{

Matrix xk = Rand(jc,1,-2,2);

[[k,xk]]

});

Set Axc = For(1,itemKey,Set(Real k)

{

Matrix Axck = Ac[1][2]*xc[k][2];

[[k,Axck]]

});

Set e = For(1,itemKey,Set(Real k)

{

Matrix ek = Gaussian(i,1, 0, .01);

[[k,ek]]

});

Set b = For(1,itemKey,Set(Real k)

{

Matrix ek = Axc[k][2]+Ax[k][2]+e[k][2];

[[k,ek]]

});

Real DBMatSetSaveFile("MA_A",A);

Real DBMatSetSaveFile("MA_x",x);

Real DBMatSetSaveFile("MA_Ax",Ax);

Real DBMatSetSaveFile("MA_Ac",Ac);

Real DBMatSetSaveFile("MA_xc",xc);

Real DBMatSetSaveFile("MA_Axc",Axc);

Real DBMatSetSaveFile("MA_e",e);

Real DBMatSetSaveFile("MA_b",b);

Set DBMatSetLoad("MA_A");

Set DBMatSetLoad("MA_Ac");

Real DBMatSetClose(0);

/* FIN DEL FICHERO: DBMatSetProof04.TOL */

4.2.5 DBMatSetProof05.TOL

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetProof05.TOL

// PURPOSE : Prueba por simulación del algoritmo de estimación lineal

// reducida.

// Utiliza las funciones de importación y exportación de DBMatSet

// para guardar en la base de datos las matrices aleatorias

// generadas en SQL necesarias para la prueba del algoritmo de

// Lanczos.

// Las matrices generadas pueden ser todo lo grandes que admitan

// la computadora y la base de datos, aunque la generación aleatoria

// en SQL no es demasiado fiable.

// Úsese para hacer pruebas de consumo de recursos como tiempo de

// proceso, memoria RAM, memoria virtual, disco, etc.

// Después de compilar este fichero hay que descompilarlo y

// compilar DBMatSetProof06.TOL para completar la prueba.

//////////////////////////////////////////////////////////////////////////////

Set Include("_initDBMatSet.tol");

Real DBMatSetOpen(0);

//////////////////////////////////////////////////////////////////////////////

// Definición de las dimensiones de la simulación:

//

// itemKey : Número de matrices (Volumen de la masividad).

// i : Número de filas por matriz (Tamaño muestral).

// j : Número de columnas por matriz (Número de variables).

//

// OJO: El número total de registros creados es

//

// itemKey*i*j

//

// así que hay que tener cuidado.

//////////////////////////////////////////////////////////////////////////////

Real itemKey = 100;

Real i = 1000;

Real j = 10;

Text grCond = "A.itemKey=1";

Real g = 1;

Real jc = 90;

//Creación de la tabla dual si no existe.

Real dual = If(DBExistTable("dual"),0,

{

DBWExecQuery("CREATE TABLE dual( [unused] [char] NULL) ON [PRIMARY];")

});

Real MA_gen_k = If(DBExistTable("MA_gen_k"),0,

{

WriteLn("Creando la tabla auxiliar MA_gen_k. Time"+Time);

Real DBWExecQuery("

CREATE TABLE MA_gen_k

(

[k] [int] NOT NULL,

[r_itemKey] [float] NOT NULL,

Bayes Forecast [email protected] http://www.bayesforecast.com/

15

[r_i] [float] NOT NULL,

[r_j] [float] NOT NULL

) ON [PRIMARY];");

Real BlockSize = 100;

Real MaxBlocks = 20;

WriteLn("Rellenando la tabla auxiliar MA_gen_k con "+

IntText(BlockSize*MaxBlocks)+" registros. Time"+Time);

Set For(0, MaxBlocks-1, Real(Real block)

{

Real k0 = block*BlockSize;

Real DBWExecQuery("insert into MA_gen_k "+

SetSum(For(k0+1,k0+BlockSize, Text(Real k)

{

If(EQ(k,k0+1),"\n ","\n union all ")+

"select

"+IntText(k)+",

"<<Rand(0,1)+",

"<<Rand(0,1)+",

"<<Rand(0,1)+"

from dual"

})));

WriteLn(" "+IntText(k0+BlockSize)+" registros insertados. Time : "+Time);

1

});

Real DBWExecQuery("CREATE UNIQUE INDEX MA_gen_k_PK ON MA_gen_k (k);");

1

});

//////////////////////////////////////////////////////////////////////////////

Real DBGenSimDimTable(Text D, Text field, Real dim)

//////////////////////////////////////////////////////////////////////////////

{

If(!DBExistTable("MA_gen_"+D), 0,

Real DBWExecQuery("drop table MA_gen_"+D+";"));

WriteLn("Creando la tabla auxiliar MA_gen_"+D+". Time"+Time);

Real DBWExecQuery("

CREATE TABLE MA_gen_"+D+"

(

["+field+"] [int] NOT NULL,

[r_"+field+"] [float] NOT NULL

) ON [PRIMARY];");

WriteLn("Rellenando la tabla auxiliar MA_gen_"+D+" con "+IntText(dim)+

" registros. Time"+Time);

Real DBWExecQuery("

insert into MA_gen_"+D+"

select k, r_"+field+" from MA_gen_k

where k<="+IntText(dim)+";");

Real DBWExecQuery("CREATE UNIQUE INDEX PK_MA_gen_"+D+"_"+field+

" ON MA_gen_"+D+" ("+field+");");

1

};

Real MA_gen_itemKey = DBGenSimDimTable("itemKey", "itemKey", itemKey);

Real MA_gen_i = DBGenSimDimTable("i", "i", i);

Real MA_gen_j = DBGenSimDimTable("j", "j", j);

Real MA_gen_g = DBGenSimDimTable("g", "itemKey", g);

Real MA_gen_jc = DBGenSimDimTable("jc", "j", jc);

WriteLn("\nGenerating Ac. Time"+Time);

Real DBMatSetCreateTable("MA_Ac");

Real DBWExecQuery("

insert into MA_Ac

select itemKey, i, j, x from (

select

itemKey, i, j,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_i+r_j)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*4 as x

from MA_gen_g, MA_gen_i, MA_gen_jc

) as aux;");

WriteLn("\nIndexing Ac. Time"+Time);

Real DBMatSetCreateIndex("MA_Ac");

WriteLn("\nGenerating xc. Time"+Time);

Real DBMatSetCreateTable("MA_xc");

Real DBWExecQuery("

insert into MA_xc

select itemKey, j, i, x from (

select

itemKey, j, 1 as i,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_j)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*4 as x

from MA_gen_itemKey, MA_gen_jc

) as aux;");

WriteLn("\nIndexing xc. Time"+Time);

Real DBMatSetCreateIndex("MA_xc");

WriteLn("\nGenerating A. Time"+Time);

Real DBMatSetCreateTable("MA_A");

Real DBWExecQuery("

insert into MA_A

select itemKey, i, j, x from (

select

itemKey, i, j,

Bayes Forecast http://www.bayesforecast.com/ [email protected]

16

(cast((8191*(8191*(8191*(8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_i+r_j)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*4 as x

from MA_gen_itemKey, MA_gen_i, MA_gen_j

) as aux;");

WriteLn("\nIndexing A. Time"+Time);

Real DBMatSetCreateIndex("MA_A");

WriteLn("\nGenerating x. Time"+Time);

Real DBMatSetCreateTable("MA_x");

Real DBWExecQuery("

insert into MA_x

select itemKey, j, i, x from (

select

itemKey, j, 1 as i,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_j)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*4 as x

from MA_gen_itemKey, MA_gen_j

) as aux;");

WriteLn("\nIndexing x. Time"+Time);

Real DBMatSetCreateIndex("MA_x");

WriteLn("\nGenerating e. Time"+Time);

Real DBMatSetCreateTable("MA_e");

Real DBWExecQuery("

insert into MA_e

select itemKey, i, j, x from (

select

itemKey, i, 1 as j,

(cast((8191*(8191*(8191*(8191*(8191*(8191*(8191*(

(8191*cast((r_itemKey+r_i)*131071/3 as int))%131071)

%131071)%131071)%131071)%131071)%131071)%131071)%131071)

as float)/131071-0.5)*.01 as x

from MA_gen_itemKey, MA_gen_i

) as aux;");

WriteLn("\nIndexing e. Time"+Time);

Real DBMatSetCreateIndex("MA_e");

Real DBMatSetTrasposedProduct("MA_test", "MA_e", "MA_e");

Set Table([[ DBTable("select * from MA_test;") ]],"Std");

Real DBWExecQuery("drop table MA_test;");

WriteLn("\nGenerating b. Time"+Time);

Real DBMatSetGroupedProduct ("MA_Axc", "MA_Ac", "MA_xc", grCond );

Real DBMatSetProduct ("MA_Ax", "MA_A", "MA_x");

Real DBMatSetSum ("MA_AxcAx", "MA_Axc", "MA_Ax");

Real DBMatSetSum ("MA_b", "MA_AxcAx", "MA_e");

/* */

Real DBMatSetClose(0);

/* FIN DEL FICHERO DBMatSetProof05.tol */

4.2.6 DBMatSetProof06.TOL

//////////////////////////////////////////////////////////////////////////////

// FILE : DBMatSetProof06.TOL

// PURPOSE : Prueba por simulación del algoritmo de estimación lineal

// reducida.

// Llama a la función de resolución reducida de sistemas lineales y

// comprueba que el resultado es correcto.

// Antes de ejecutar este fichero es necesario que existan en las

// base de datos las tablas generadas por DBMatSetProof04.TOL o por

// DBMatSetProof05.TOL

//////////////////////////////////////////////////////////////////////////////

Set Include("_initDBMatSet.tol");

Real DBMatSetOpen(0);

Set Table([[ DBTable("

select

itemKey, Sqrt(Avg(x*x)) from MA_e

group by itemkey

order by itemkey;

")]],"Std");

Text grCond = "A.itemKey=1";

//*

Real DBMatSetGroupedProduct ("MA_Axc_", "MA_Ac", "MA_xc", grCond );

Real DBMatSetProduct ("MA_Ax_", "MA_A", "MA_x");

Real DBMatSetSum ("MA_AxcAx_", "MA_Axc_", "MA_Ax_");

Real DBMatSetSubstract ("MA_e_", "MA_b", "MA_AxcAx_");

WriteLn("\nTest e_");

Set Table([[ DBTable("

select

itemKey, Sqrt(Avg(x*x)) from MA_e_

group by itemkey

order by itemkey;

")]],"Std");

Bayes Forecast [email protected] http://www.bayesforecast.com/

17

/* */

//*

Real DBMatSetReducedMinResSolve ("MA_xc_", "MA_Ac",

"MA_x_", "MA_A",

"MA_b", grCond);

Real DBMatSetProduct ("MA_AcPAc", "MA_Ac_SVD_P", "MA_Ac");

Real DBMatSetTrasposedProduct("MA_Ac_SVD_UtU", "MA_Ac_SVD_U", "MA_Ac_SVD_U");

Real DBMatSetTrasposedProduct("MA_Ac_SVD_VtV", "MA_Ac_SVD_V", "MA_Ac_SVD_V");

Real DBMatSetGroupedProduct ("MA_Axc_", "MA_Ac", "MA_xc_", grCond );

Real DBMatSetProduct ("MA_Ax_", "MA_A", "MA_x_");

Real DBMatSetSum ("MA_AxcAx_", "MA_Axc_", "MA_Ax_");

Real DBMatSetSubstract ("MA_e_", "MA_b", "MA_AxcAx_");

Real DBMatSetSubstract ("MA_xD", "MA_x", "MA_x_");

Real DBMatSetSubstract ("MA_xcD", "MA_xc", "MA_xc_");

WriteLn("\nTest e_");

Set Table([[ DBTable("

select

itemKey, Sqrt(Avg(x*x)) from MA_e_

group by itemkey

order by itemkey;

")]],"Std");

WriteLn("\nTest dif x-x_");

Set Table([[ DBTable("

select

itemKey, max(Abs(x)) from MA_xD

group by itemkey

order by itemkey;

")]],"Std");

WriteLn("\nTest dif xc-xc_");

Set Table([[ DBTable("

select

itemKey, max(Abs(x)) from MA_xcD

group by itemkey

order by itemkey;

")]],"Std");

/* */

Real DBMatSetClose(0);

/* FIN DEL FICHERO: DBMatSetProof06.TOL */

Bayes Forecast [email protected] http://www.bayesforecast.com/

1

BIBLIOGRAFÍA i Lanczos bidiagonalization with partial reorthogonalization (October 1988)

Rasmus Munk Larsen (Departement of Computer Science University of Aarhus)

Ny Munkehade building 540 DK-8000 Aarhus C

e-mail [email protected]

ii Métodos numéricos para la regresión lineal (Marzo 2001)

Víctor de Buen (Bayes Inference S.A. www.bayesforecast.com)

e-mail [email protected]