﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	severity	resolution	keywords	cc
1048	Vectores de referencias a valores double internos de las variables TOL	Víctor de Buen Remiro	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'''
   {{{
#!cpp
//Creates a single reference to a Real variable
VectorRef Ref.Real(Real x);
}}}
 * '''Polyn'''
   {{{
#!cpp
//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'''
   {{{
#!cpp
//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'''
   {{{
#!cpp
//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'''
   {{{
#!cpp
//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.
{{{
#!cpp
//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

{{{
#!cpp
  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

{{{
#!cpp
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
{{{
#!cpp
//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.
"	task	accepted	low	Numerical methods	Math		minor			
