Dear co-rooters,
I am trying to playing with matrices in root.
Since I experienced some issues using TMatrix
and SMatrix
(Resizing and transposing a TMatrixFSparse - row/col indices are not set, Cannot transpose a TMatrixFSparse matrix - Error in : matrix has wrong shape, TMatrix for large matrices, Using SMatrix for large matrices) so I used the boost
library after the suggestion of @Wile_E_Coyote
The first try to build a symmetric matrix using an array can be seen below
//#if !defined(__CINT__)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>// std::max()
#include <iterator>
#include </usr/include/boost/numeric/ublas/matrix.hpp>
#include </usr/include/boost/numeric/ublas/matrix_sparse.hpp>
#include </usr/include/boost/numeric/ublas/symmetric.hpp>
#include </usr/include/boost/numeric/ublas/io.hpp>
//#endif /* !defined(__CINT__) */
#include "covariance_lib.cc"//The function fill_symmetric has an issue - begin(array) throws an error
using namespace std;
int test_boost () {
using namespace boost::numeric::ublas;
symmetric_matrix<double, upper> m_sym1 (3, 3);
float filler[6] = {0, 1, 2, 3, 4, 5};
float const* in1 = std::begin(filler);
for (size_t i = 0; i < m_sym1.size1(); ++ i)
for (size_t j = 0; j <= i && in1 != std::end(filler); ++ j)
m_sym1 (i, j) = *in1++;
std::cout << m_sym1 << std::endl;
symmetric_matrix<float, upper> m_sym (3, 3);
m_sym1 = fill_symmetric( m_sym1, filler);
std::cout << m_sym << std::endl;
return 0;
}
where covariance_lib.cc
can be seen below
// Inputs : -name = name of the ascii file to be read - two column file with x and y values, rescpectively assumed
// -X_USER = array that contains the user defined energy binning
// -output = if output = TRUE exports the interpolation array
// if output = FALSE exports the index of the input values used in the interpolation
void linear_interpolation(int size_USER, int size_EVAL, float* X_USER, float* Y_USER, float* X_EVAL, float* Y_EVAL, int* index){
float x1, x2,y1, y2, a, b;
bool boo;
x1 = 0.; x2 = 0.; y1 = 0; y2 = 0.; a = 0.; b = 0.;
for(int i=0; i<=size_USER; ++i){
boo = true;
for (int j=0; j<=size_EVAL; j++){
if (boo==true){
if(X_USER[i] == X_EVAL[j]){
Y_USER[i] = Y_EVAL[j];
index[i] = j;
boo = false;
}
else if(X_USER[i]>X_EVAL[j]){
x1 = X_EVAL[j];
y1 = Y_EVAL[j];
index[i] = j;
}
else if( X_USER[i]<X_EVAL[j] && boo == true ){
x2 = X_EVAL[j];
y2 = Y_EVAL[j];
a = (y2-y1)/(x2-x1);
b = y2-a*x2;
Y_USER[i] = a*X_USER[i]+b;
//index[i] = j;
boo = false;
}
}
}//end of loop over EVAL
}//end of loop over USER
}//____linear_interpolation()
void input_ascii(TString filename, float* X_EVAL, float* Y_EVAL){
std::ifstream myfile;
myfile.open(filename);
float x = 0, y = 0;
int i = 0;
while(1){
myfile >> x >> y;
if (!myfile.good()) break;
X_EVAL[i] = x;
Y_EVAL[i] = y;
i++;
}
myfile.close();
}//___input_ascii()
int count_lines(TString filename){
float x, y;
int nlines;
// (1) Open the file to count its lines
std::ifstream myfile;
myfile.open(filename);
if(!myfile){
cout << "File not found" << endl;
}
nlines = 0;
while(1){
myfile >> x >> y;
if (!myfile.good()) break;
nlines++;
}
myfile.close();
return nlines;
}//___count_lines()
std::vector<float> isolethargic_binning(int min, int max, int bpd){
int ndec = max - min;
int nbins = (int) ndec*bpd;
float step = (float) ndec / nbins;
std::vector<float> xbins(nbins+1);
for(int i=0; i <= nbins; i++) {
xbins[i] = (float) pow(10., step * (float) i + min);
}
return xbins;
}//___isolethargic_binning()
boost::numeric::ublas::symmetric_matrix<float> fill_symmetric (boost::numeric::ublas::symmetric_matrix<float> m_sym, float* filler){
//assert(("ERROR! Filler's dimension have to be n*(n+1)/2!", sizeof(filler)/sizeof(filler[0]) == m_sym.size2() ));
float const* in = std::begin(filler);
for (size_t i = 0; i < m_sym.size1(); ++ i)
for (size_t j = 0; j <= i && in != std::end(filler); ++ j)
m_sym (i, j) = *in++;
return m_sym;
}//___fill_symmetric
The problem is when compiling the code (ACLiC
using ROOT6
on lxplus) I get the following output
root [1] .L boost.C++
Info in <TUnixSystem::ACLiC>: creating shared library /eos/user/a/astamato/covariance/code/./boost_C.so
Warning in cling::IncrementalParser::CheckABICompatibility():
C++ ABI mismatch, compiled with __GLIBCXX__ v20130531 running with v20141219
In file included from input_line_12:9:
In file included from ././boost.C:27:
./covariance_lib.cc:96:20: error: no matching function for call to 'begin'
float const* in = std::begin(filler);
^~~~~~~~~~
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/bits/range_access.h:48:5: note: candidate template ignored: substitution failure
[with _Container = float *]: member reference base type 'float *' is not a structure or union
begin(_Container& __cont) -> decltype(__cont.begin())
^ ~
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/bits/range_access.h:58:5: note: candidate template ignored: substitution failure
[with _Container = float *]: member reference base type 'float *const' is not a structure or union
begin(const _Container& __cont) -> decltype(__cont.begin())
^ ~
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/bits/range_access.h:87:5: note: candidate template ignored: could not match
'_Tp [_Nm]' against 'float *'
begin(_Tp (&__arr)[_Nm])
^
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/initializer_list:89:5: note: candidate template ignored: could not match
'initializer_list<type-parameter-0-0>' against 'float *'
begin(initializer_list<_Tp> __ils) noexcept
^
In file included from input_line_12:9:
In file included from ././boost.C:27:
./covariance_lib.cc:99:42: error: no matching function for call to 'end'
for (size_t j = 0; j <= i && in != std::end(filler); ++ j)
^~~~~~~~
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/bits/range_access.h:68:5: note: candidate template ignored: substitution failure
[with _Container = float *]: member reference base type 'float *' is not a structure or union
end(_Container& __cont) -> decltype(__cont.end())
^ ~
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/bits/range_access.h:78:5: note: candidate template ignored: substitution failure
[with _Container = float *]: member reference base type 'float *const' is not a structure or union
end(const _Container& __cont) -> decltype(__cont.end())
^ ~
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/bits/range_access.h:97:5: note: candidate template ignored: could not match
'_Tp [_Nm]' against 'float *'
end(_Tp (&__arr)[_Nm])
^
/afs/cern.ch/sw/lcg/contrib/gcc/4.8.4/x86_64-slc6/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../include/c++/4.8.4/initializer_list:99:5: note: candidate template ignored: could not match
'initializer_list<type-parameter-0-0>' against 'float *'
end(initializer_list<_Tp> __ils) noexcept
^
Error in <ACLiC>: Dictionary generation failed!
It seems that the error is in the function fill_symmetric()
and I don’t get why begin(array)
gives an error!
The even strangest thing is that if I execute the filling in the main code, it works fine!
Any idea why this is happening and how to fix it?
Thanks in advance!