Opened 14 years ago
Last modified 14 years ago
#1048 accepted task
Vectores de referencias a valores double internos de las variables TOL
Reported by: | Víctor de Buen Remiro | Owned by: | Víctor de Buen Remiro |
---|---|---|---|
Priority: | low | Milestone: | Numerical methods |
Component: | Math | Version: | |
Severity: | minor | Keywords: | |
Cc: |
Description (last modified by )
En procesos de cálculo numérico de gran complejidad como la estimación o simulación de modelos estadísticos se utilizan usualmente estructuras de datos bastante intrincadas que incluyen los datos conocidos y las variables cuyos valores se desea conocer.
Sin embargo, los algoritmos matemáticos están pensados para trabajar con simples vectores o matrices con los datos convenientemente colocados.
Por ejemplo, para manipular un modelo ARIMA, es necesario un conjunto de factores que son a su vez conjuntos que incluyen la periodicidad que es un número entero y los polinomios DIF, AR y MA. Tanto la periodicidad como las diferencias son datos conocidos mientras que en los polinomios AR y MA el coeficiente de grado 0 es siempre 1 y el resto de coeficientes son las variables del modelo. Para hacer ciertas operaciones, como la aplicación del filtro a una serie, conviene mantener la estructura de conjuntos de polinomios, pero para otras, como la aplicación de un método típico de optimización, conviene tener un vector con sólo los valores de las variables.
En un marco más general podríamos hablar de que existen operaciones estructurales y operaciones vectoriales, en el sentido de que las primeras se efectúan más cómoda y eficientemente usando las estructuras de datos originales, mientras que las segundas se realizan mucho mejor usando arreglos.
Si las operaciones estructurales y las vectoriales se suceden en el tiempo de forma alternativa dentro de un ciclo entonces es necesario pasar de una forma a la otra en cada iteración, lo cual puede llegar a ser muy ineficaz.
La solución más razonable para tratar con este tipo de problemas es el uso de referencias, de forma que la forma vectorial de los datos apunte realmente a la posición de memoria en la estructura original. De esta forma, cualquier cambio en una forma se ve automáticamente reflejado en la otra sin coste alguno.
Este tipo de tratamiento puede ser especialmente útil combinado con el uso de TolCint pero desde el propio TOL también se le puede sacar
un gran partido.
La solución que se propone sería crear un nuevo tipo de datos en TOL
que podría llamarse VectorRef
y que tendría funciones para ir añadiendo referencias a valores reales inscritos en distintos tipos de datos TOL. En principio se podrían crear referencias simples o masivas a datos de estos tipos
- Real
//Creates a single reference to a Real variable VectorRef Ref.Real(Real x);
- Polyn
//Creates a single reference to a coefficient of a polynomial VectorRef Ref.Polyn.Coef(Polyn pol, Real deg)); //Creates a vectorial reference to all coefficients of a polynomial among a selection of degrees VectorRef Ref.Polyn.Extract(Polyn pol, Set degrees)); //Creates a vectorial reference to all coefficients of a polynomial VectorRef Ref.Polyn.Full(Polyn pol));
- Matrix
//Creates a single reference to a cell in a Matrix VectorRef Ref.Matrix.Cell(Matrix mat, Real row, Real column)); //Creates a vectorial reference to all cells in a rectangle of a Matrix VectorRef Ref.Matrix.Minor(Matrix mat, Real fromRow, Real fromColumn, Real untilRow, Real untilColumns)); //Creates a vectorial reference to all cells in a subset of selected rows from a Matrix VectorRef Ref.Matrix.Rows(Matrix mat, Set rowIndexs)); //Creates a vectorial reference to all cells in a subset of selected coluns from a Matrix VectorRef Ref.Matrix.Columns(Matrix mat, Set colIndexs)); //Creates a vectorial reference to all cells in a Matrix VectorRef Ref.Matrix.Full(Matrix mat, Set colIndexs));
- Set
//Creates a single reference to a Real element of a Set VectorRef Ref.Set.Element(Set set, Real numElement)); //Creates a vectorial reference to all selected elements of a Set VectorRef Ref.Set.Extract(Set set, Set indexes)); //Creates a vectorial reference to all selected elements of a Set with type Real VectorRef Ref.Set.Full(Set set)); //Creates a vectorial reference to all selected elements of a Set with type Real, Polyn or Matrix, and recursively in elements of type Set or NameBlock VectorRef Ref.Set.Deep(Set set));
- NameBlock
//Creates a single reference to a Real member of a NameBlock VectorRef Ref.NameBlock.Element(NameBlock nb, Real numElement)); //Creates a vectorial reference to all selected members of a NameBlock VectorRef Ref.NameBlock.Extract(NameBlock nb, Set indexes)); //Creates a vectorial reference to all selected members of a NameBlock with type Real VectorRef Ref.NameBlock.Full(NameBlock nb)); //Creates a vectorial reference to all selected members of a NameBlock with type Real, Polyn or Matrix, and recursively in elements of type Set or NameBlock VectorRef Ref.NameBlock.Deep(NameBlock nb));
Sería necesario también disponer de algunas funciones para la definición de vectores de referencia a partir de otros mediante composición y extracción.
//Añade al primer vector de referecias las del segundo VectorRef Ref.Append(VectorRef a, VectorRef b); //Extrae las referencias seleccionadas VectorRef Ref.Extract(VectorRef a, Real indexes);
Para su uso con CINT haría falta una función de exportación
Real Cint.ExportRef(VectorRef a [, Text nameSpace=""])
lo cual crearía en el ámbito global o el namespace especificado una instancia de la clase con el nombre de la variable exportada
class VectorRef { private: int s_; double** ref_; public: VectorRef(int s, double** ref) : s_(s), ref_(ref) {} ~VectorRef() {} int size() const; //zero based const array access const double & operator [] (int i) const { return (*ref_[i]); } //zero based non const array access double & operator [] (int i) { return (*ref_[i]); } //one based const array access const double & operator () (int i) const { return (*ref_[i-1]); } //one based non const array access double & operator () (int i) { return (*ref_[i-1]); } //set the referenced values from an std::vector void setValues(const std::vector<double>& v) { if(v.size()==s_) { int i; double* rf = ref_; for(i=0; i<s; i++, rf++) { *rf = v[i]; } } } //get the referenced values into a std::vector void getValues(std::vector<double>& v) const { if(v.size()==s_) { int i; double* rf = ref_; for(i=0; i<s; i++, rf++) { v[i] = *rf; } } }; //set the referenced values from a pointer to double void setValues(const double* v) { int i; double* rf = ref_; const double* v_ = ref_; for(i=0; i<s; i++, rf++, v_++) { *rf = *v_; } } //get the referenced values into a a pointer to double void getValues(double* v) const { int i; double* rf = ref_; const double* v_ = ref_; for(i=0; i<s; i++, rf++, v_++) { *v_ = *rf; } };
Finalmente haría falta una función para lectura y escritura desde y a Matrix
//Devuelve una matriz columna con los valores referenciados Matrix v = Ref.Get(vr); //Modifica los valores referenciados haciéndolos iguales a los elementos de una matriz columna con el mismo número de elementos Real Ref.Put(vr,v*2);
De esta forma en cada iteración de un hipotético ciclo TOL sólo sería necesario llamar una vez a cada una de estas dos funciones.
Change History (3)
comment:1 Changed 14 years ago by
Description: | modified (diff) |
---|---|
Status: | new → accepted |
comment:2 Changed 14 years ago by
Description: | modified (diff) |
---|
comment:3 Changed 14 years ago by
Priority: | highest → low |
---|---|
Severity: | blocker → minor |