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 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 Víctor de Buen Remiro)

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 Víctor de Buen Remiro

Description: modified (diff)
Status: newaccepted

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

Description: modified (diff)

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

Priority: highestlow
Severity: blockerminor
Note: See TracTickets for help on using tickets.