returning sparse matrix in compressed format

issue#70
Michel Juillard 2013-10-13 17:49:10 +02:00
parent 6e0ef026ac
commit 17d0177276
2 changed files with 98 additions and 163 deletions

View File

@ -4511,10 +4511,8 @@ DynamicModel::writeSecondDerivativesCC_csr(const string &basename, bool cuda) co
deriv_node_temp_terms_t tef_terms;
// Indexing derivatives in column order
vector<int> d_order(NNZDerivatives[1]);
OrderByLinearAddress obla(NNZDerivatives[1]);
int counter = 0;
int dynHessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
vector<derivative> D;
int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
it != second_derivatives.end(); it++)
{
@ -4526,61 +4524,32 @@ DynamicModel::writeSecondDerivativesCC_csr(const string &basename, bool cuda) co
int id2 = getDynJacobianCol(var2);
int col_nb = id1 * dynJacobianColsNbr + id2;
int col_nb_sym = id2 * dynJacobianColsNbr + id1;
obla.linear_address[counter] = col_nb + eq*dynHessianColsNbr;
d_order[counter] = counter;
++counter;
derivative deriv(col_nb + eq*hessianColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
if (id1 != id2)
{
obla.linear_address[counter] = col_nb_sym + eq*dynHessianColsNbr;
d_order[counter] = counter;
++counter;
col_nb = id2 * dynJacobianColsNbr + id1;
derivative deriv(col_nb + eq*hessianColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
}
}
sort(d_order.begin(), d_order.end(), obla);
sort(D.begin(), D.end(), derivative_less_than() );
// Writing Hessian
vector<int> row_ptr(equations.size());
fill(row_ptr.begin(),row_ptr.end(),0.0);
int k = 0; // Keep the order of a 2nd derivative
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
it != second_derivatives.end(); it++)
int k = 0;
for(vector<derivative>::const_iterator it = D.begin(); it != D.end(); ++it)
{
int eq = it->first.first;
int var1 = it->first.second.first;
int var2 = it->first.second.second;
expr_t d2 = it->second;
int id1 = getDynJacobianCol(var1);
int id2 = getDynJacobianCol(var2);
int col_nb = id1 * dynJacobianColsNbr + id2;
int col_nb_sym = id2 * dynJacobianColsNbr + id1;
row_ptr[eq]++;
mDynamicModelFile << "col_ptr[" << d_order[k] << "] "
<< "=" << col_nb << ";" << endl;
mDynamicModelFile << "value[" << d_order[k] << "] = ";
row_ptr[it->row_nbr]++;
mDynamicModelFile << "col_ptr[" << k << "] "
<< "=" << it->col_nbr << ";" << endl;
mDynamicModelFile << "value[" << k << "] = ";
// oCstaticModel makes reference to the static variables
d2->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
it->value->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl;
k++;
// Treating symetric elements
if (id1 != id2)
{
row_ptr[eq]++;
mDynamicModelFile << "col_ptr[" << d_order[k] << "] "
<< "=" << col_nb_sym << ";" << endl;
mDynamicModelFile << "value[" << d_order[k] << "] = ";
// oCstaticModel makes reference to the static variables
d2->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl;
k++;
}
}
// row_ptr must point to the relative address of the first element of the row
@ -4634,11 +4603,9 @@ DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) con
// this is always empty here, but needed by d1->writeOutput
deriv_node_temp_terms_t tef_terms;
// Indexing derivatives in column order
vector<int> d_order(NNZDerivatives[1]);
OrderByLinearAddress obla(NNZDerivatives[1]);
int counter = 0;
int dynHessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
vector<derivative> D;
int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
int thirdDerivativesColsNbr = hessianColsNbr*dynJacobianColsNbr;
for (third_derivatives_t::const_iterator it = third_derivatives.begin();
it != third_derivatives.end(); it++)
{
@ -4646,114 +4613,81 @@ DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) con
int var1 = it->first.second.first;
int var2 = it->first.second.second.first;
int var3 = it->first.second.second.second;
expr_t d3 = it->second;
int id1 = getDynJacobianCol(var1);
int id2 = getDynJacobianCol(var2);
int id3 = getDynJacobianCol(var3);
// Reference column number for the g3 matrix
int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
sparseHelper(3, mDynamicModelFile, k, 0, oCDynamicModel);
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k, 1, oCDynamicModel);
mDynamicModelFile << "=" << ref_col + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
mDynamicModelFile << "=";
// oCstaticModel makes reference to the static variables
d3->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl;
// Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal)
set<int> cols;
cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2);
cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3);
cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1);
cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2);
cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1);
int k2 = 1; // Keeps the offset of the permutation relative to k
for (set<int>::iterator it2 = cols.begin(); it2 != cols.end(); it2++)
if (*it2 != ref_col)
{
sparseHelper(3, mDynamicModelFile, k+k2, 0, oCDynamicModel);
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k+k2, 1, oCDynamicModel);
mDynamicModelFile << "=" << *it2 + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k+k2, 2, oCDynamicModel);
mDynamicModelFile << "=";
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
mDynamicModelFile << ";" << endl;
k2++;
}
k += k2;
// Reference column number for the g3 matrix (with symmetrical derivatives)
vector<long unsigned int> cols;
long unsigned int col_nb = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
int thirdDColsNbr = hessianColsNbr*dynJacobianColsNbr;
derivative deriv(col_nb + eq*thirdDColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
cols.push_back(col_nb);
col_nb = id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
{
derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
cols.push_back(col_nb);
}
col_nb = id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
{
derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
cols.push_back(col_nb);
}
col_nb = id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
{
derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
cols.push_back(col_nb);
}
col_nb = id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
{
derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
cols.push_back(col_nb);
}
col_nb = id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
{
derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
}
}
// Writing third derivatives
int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr;
int k = 0; // Keep the line of a 3rd derivative in v3
for (third_derivatives_t::const_iterator it = third_derivatives.begin();
it != third_derivatives.end(); it++)
sort(D.begin(), D.end(), derivative_less_than() );
vector<int> row_ptr(equations.size());
fill(row_ptr.begin(),row_ptr.end(),0.0);
int k = 0;
for(vector<derivative>::const_iterator it = D.begin(); it != D.end(); ++it)
{
int eq = it->first.first;
int var1 = it->first.second.first;
int var2 = it->first.second.second.first;
int var3 = it->first.second.second.second;
expr_t d3 = it->second;
int id1 = getDynJacobianCol(var1);
int id2 = getDynJacobianCol(var2);
int id3 = getDynJacobianCol(var3);
// Reference column number for the g3 matrix
int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
sparseHelper(3, mDynamicModelFile, k, 0, oCDynamicModel);
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k, 1, oCDynamicModel);
mDynamicModelFile << "=" << ref_col + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
mDynamicModelFile << "=";
row_ptr[it->row_nbr]++;
mDynamicModelFile << "col_ptr[" << k << "] "
<< "=" << it->col_nbr << ";" << endl;
mDynamicModelFile << "value[" << k << "] = ";
// oCstaticModel makes reference to the static variables
d3->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
it->value->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl;
// Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal)
set<int> cols;
cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2);
cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3);
cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1);
cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2);
cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1);
int k2 = 1; // Keeps the offset of the permutation relative to k
for (set<int>::iterator it2 = cols.begin(); it2 != cols.end(); it2++)
if (*it2 != ref_col)
{
sparseHelper(3, mDynamicModelFile, k+k2, 0, oCDynamicModel);
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k+k2, 1, oCDynamicModel);
mDynamicModelFile << "=" << *it2 + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k+k2, 2, oCDynamicModel);
mDynamicModelFile << "=";
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
mDynamicModelFile << ";" << endl;
k2++;
}
k += k2;
k++;
}
// row_ptr must point to the relative address of the first element of the row
int cumsum = 0;
mDynamicModelFile << "row_ptr = [ 0";
for (vector<int>::iterator it=row_ptr.begin(); it != row_ptr.end(); ++it)
{
cumsum += *it;
mDynamicModelFile << ", " << cumsum;
}
mDynamicModelFile << "];" << endl;
mDynamicModelFile << "}" << endl;
writePowerDeriv(mDynamicModelFile, true);
@ -4761,13 +4695,4 @@ DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) con
}
OrderByLinearAddress::OrderByLinearAddress(int size)
{
linear_address.resize(size);
}
bool OrderByLinearAddress::operator()(const int i1, const int i2) const
{
return linear_address[i1] < linear_address[i2];
}

View File

@ -473,14 +473,24 @@ public:
bool isModelLocalVariableUsed() const;
};
//! Class to re-order derivatives for various sparse storage formats
class OrderByLinearAddress
//! Classes to re-order derivatives for various sparse storage formats
class derivative
{
public:
//! vector of linear addresses in derivatives matrices
vector<long unsigned int> linear_address;
OrderByLinearAddress(int size);
//! Order by linear address in a matrix
bool operator()(const int i1, const int i2) const;
long unsigned int linear_address;
long unsigned int col_nbr;
unsigned int row_nbr;
expr_t value;
derivative(long unsigned int arg1, long unsigned int arg2, int arg3, expr_t arg4):
linear_address(arg1), col_nbr(arg2), row_nbr(arg3), value(arg4) {};
};
class derivative_less_than
{
public:
bool operator()(const derivative & d1, const derivative & d2) const
{
return d1.linear_address < d2.linear_address;
}
};
#endif