Discussion:
[eigen] SparseMatrix triangularView
Brad Bell
2017-08-07 21:45:39 UTC
Permalink
Why does the template parameter Scalar in test_case<Scalar>, not act
like 'double', when compiling
test_case<double> ?

Below you will find a bash script that demonstrates this.
When I run it on my system I get:

trash>./eigen_example.sh
g++ (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)
./eigen_example
x^T = 1 2 3
We got the expected result: x^T = 1 2 3
Now change SparseMatrix<double> to SparseMatrix<Scalar> and recompile:
eigen_example.cpp: In function ‘Eigen::Matrix<Scalar, -1, 1>
test_case(Eigen::Matrix<Scalar, -1, 1>&)’:
eigen_example.cpp:13:64: error: expected primary-expression before ‘)’ token
Matrix<Scalar, Dynamic, 1> x = M.triangularView<Eigen::Lower>().solve(y);
... snip ...


#!/bin/bash -e
eigen_prefix="$HOME/prefix/eigen"
if [ ! -e "$eigen_prefix/include/Eigen/Dense" ]
then
echo "Must set eigen_prefix to proper value for this system"
exit 1
fi
#
----------------------------------------------------------------------------
cat << EOF > eigen_example.cpp
# include <iostream>
# include <Eigen/Dense>
# include <Eigen/SparseCore>

using Eigen::Matrix;
using Eigen::Dynamic;
template <class Scalar> Matrix<Scalar, Dynamic, 1>
test_case(Matrix<Scalar, Dynamic, 1>& y)
{ int n = y.size();
Eigen::SparseMatrix<double> M(n, n);
for(int i = 0; i < n; i++)
M.insert(i, i) = Scalar(1.0);
Matrix<Scalar, Dynamic, 1> x = M.triangularView<Eigen::Lower>().solve(y);
return x;
}
int main() {
int n = 3;
Matrix<double, Dynamic, 1> y(n);
for(int i = 0; i < n; i++)
y(i) = double(i + 1);
Matrix<double, Dynamic, 1> x = test_case<double>(y);
std::cout << "x^T = " << x.transpose() << "\n";
return 0;
}
EOF
#
----------------------------------------------------------------------------
g++ --version | head -1
g++ -Wall -I$eigen_prefix/include eigen_example.cpp -o eigen_example
echo './eigen_example'
./eigen_example
echo 'We got the expected result: x^T = 1 2 3'
#
----------------------------------------------------------------------------
echo 'Now change SparseMatrix<double> to SparseMatrix<Scalar> and
recompile:'
sed -i eigen_example.cpp -e 's|SparseMatrix<double>|SparseMatrix<Scalar>|'
g++ -Wall -I$eigen_prefix/include eigen_example.cpp -o eigen_example
Gael Guennebaud
2017-08-09 08:11:33 UTC
Permalink
In the templated case you need to add the 'template' keyword (analogue of
typedef for templated methods) as required by the C++ standard:

M.template triangularView<Eigen::Lower>()

See also: https://eigen.tuxfamily.org/dox/TopicTemplateKeyword.html for
more details.

Gael
Why does the template parameter Scalar in test_case<Scalar>, not act like
'double', when compiling
test_case<double> ?
Below you will find a bash script that demonstrates this.
trash>./eigen_example.sh
g++ (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)
./eigen_example
x^T = 1 2 3
We got the expected result: x^T = 1 2 3
eigen_example.cpp: In function ‘Eigen::Matrix<Scalar, -1, 1>
eigen_example.cpp:13:64: error: expected primary-expression before ‘)’
token
Matrix<Scalar, Dynamic, 1> x = M.triangularView<Eigen::Lower>
().solve(y);
... snip ...
#!/bin/bash -e
eigen_prefix="$HOME/prefix/eigen"
if [ ! -e "$eigen_prefix/include/Eigen/Dense" ]
then
echo "Must set eigen_prefix to proper value for this system"
exit 1
fi
# ------------------------------------------------------------
----------------
cat << EOF > eigen_example.cpp
# include <iostream>
# include <Eigen/Dense>
# include <Eigen/SparseCore>
using Eigen::Matrix;
using Eigen::Dynamic;
template <class Scalar> Matrix<Scalar, Dynamic, 1>
test_case(Matrix<Scalar, Dynamic, 1>& y)
{ int n = y.size();
Eigen::SparseMatrix<double> M(n, n);
for(int i = 0; i < n; i++)
M.insert(i, i) = Scalar(1.0);
Matrix<Scalar, Dynamic, 1> x = M.triangularView<Eigen::Lower>
().solve(y);
return x;
}
int main() {
int n = 3;
Matrix<double, Dynamic, 1> y(n);
for(int i = 0; i < n; i++)
y(i) = double(i + 1);
Matrix<double, Dynamic, 1> x = test_case<double>(y);
std::cout << "x^T = " << x.transpose() << "\n";
return 0;
}
EOF
# ------------------------------------------------------------
----------------
g++ --version | head -1
g++ -Wall -I$eigen_prefix/include eigen_example.cpp -o eigen_example
echo './eigen_example'
./eigen_example
echo 'We got the expected result: x^T = 1 2 3'
# ------------------------------------------------------------
----------------
echo 'Now change SparseMatrix<double> to SparseMatrix<Scalar> and
recompile:'
sed -i eigen_example.cpp -e 's|SparseMatrix<double>|SparseMatrix<Scalar>|'
g++ -Wall -I$eigen_prefix/include eigen_example.cpp -o eigen_example
Joe Hellmers
2017-11-21 02:30:38 UTC
Permalink
Hello,

Does Eigen support 3D Array / 3rd Rank Tensors?

Joe Hellmers
Abhijit Kundu
2017-11-21 03:50:56 UTC
Permalink
Yes. Have a look at Tensor Module.
https://bitbucket.org/eigen/eigen/src/default/unsupported/Eigen/CXX11/src/Tensor/README.md
http://eigen.tuxfamily.org/dox-devel/unsupported/group__CXX11__Tensor__Module.html
Post by Joe Hellmers
Hello,
Does Eigen support 3D Array / 3rd Rank Tensors?
Joe Hellmers
Paul Springer
2017-11-21 08:16:36 UTC
Permalink
What kind of functionality do you need?

I found Eigen's tensor performance grossly suboptimal.

-Paul
Post by Joe Hellmers
Hello,
Does Eigen support 3D Array / 3rd Rank Tensors?
Joe Hellmers
Joe Hellmers
2017-11-22 17:18:56 UTC
Permalink
I’m looking for the ability access slices of 3D array of float or double scalar values. The slices could 2D or 1D. It would be nice to be able to serialize and deserialize the 3D array.

It doesn’t have to be C++, it could be regular C as well.

Joe Hellmers
Post by Paul Springer
What kind of functionality do you need?
I found Eigen's tensor performance grossly suboptimal.
-Paul
Post by Joe Hellmers
Hello,
Does Eigen support 3D Array / 3rd Rank Tensors?
Joe Hellmers
Loading...