I am trying to use examples from
Reduction Dimensions
section of Eigen Tensors README
This:
// Create a tensor of 2 dimensions
Eigen::Tensor<int, 2> a(2, 3);
a.setValues({{1, 2, 3}, {6, 5, 4}});
// Reduce it along the second dimension (1)...
Eigen::array<int, 1> dims({1 /* dimension to reduce */});
// ...using the "maximum" operator.
// The result is a tensor with one dimension. The size of
// that dimension is the same as the first (non-reduced) dimension of a.
Eigen::Tensor<int, 1> b = a.maximum(dims);
cout << "a" << endl << a << endl << endl;
cout << "b" << endl << b << endl << endl;
And other examples from that section gives me Error C2100 illegal indirection compile error. In VS 2015. Everything else works and compile well. Any ideas what is the problem with that code?
Eigen::array<int, 1> dims({1 /* dimension to reduce */});
Should be changed to:
const std::array<DenseIndex, 1> action_cards_dims = { 1 };
Related
I was playing around with std::list. Similarly to other containers, std::list::end refers to the past-the-end element of a std::list (ref).
So, we would expect the below code to print 1, 2, 3, 4, 5 (which it does):
std::list<int> l { 1, 2, 3, 4, 5 };
for (auto it = l.begin(); it != l.end(); ++it)
{
std::cout << *it << ", ";
}
std::cout << std::endl;
However, the second line of the second code snippet should not print 5, but it does:
std::cout << *l.begin() << std::endl;
std::cout << *l.end() << std::endl;
Output: 1 and 5.
Why? I'm using GCC 11 and C++11 (same for C++20 btw).
You can see the reason if you build in debug mode, with the -D_GLIBCXX_DEBUG command line flag:
/usr/include/c++/8/debug/safe_iterator.h:270:
Error: attempt to dereference a past-the-end iterator.
Objects involved in the operation:
iterator "this" # 0x0x7fff50ac8670 {
type = __gnu_debug::_Safe_iterator<std::__cxx1998::_List_iterator<int>, std::__debug::list<int, std::allocator<int> > > (mutable iterator);
state = past-the-end;
references sequence with type 'std::__debug::list<int, std::allocator<int> >' # 0x0x7fff50ac85d0
}
Aborted
As with other containers, dereferencing the end() iterator is undefined. It only happens to work by accident in non-debug mode.
I am using the EIGEN sparse library to solve a system. I tried to test on a smaller matrix and got the estimated error close to zero. I attach the snippet of the code below.
MatrixXd Dense(4,4);
Dense<<2.0,0.0,0.0,0.0,
0.0,1.0,0.0,1.0,
0.0,0.0,5.0,0.0,
0.0,0.0,0.0,1.0;
Vector4d b(4.0, 5.0, 8.0, 1.0),xsol;
cout << "The least-squares solution is:\n"
<< Dense.jacobiSvd(ComputeThinU | ComputeThinV).solve(b) << endl;
SpMat SparseA;
SparseA = Dense.sparseView();
cout<<SparseA<<endl;
BiCGSTAB<SparseMatrix<double> > bicg;
bicg.compute(SparseA);
xsol = bicg.solve(b);
std::cout << "#iterations: " << bicg.iterations() << std::endl;
std::cout << "estimated error: " << bicg.error() << std::endl;
// update and solve again
xsol = bicg.solve(b);
cout << "Sparse Matrix Solution is:\n" << xsol << endl;**
This is what I get when I run the code:
iterations: 1
estimated error: 0
Sparse Matrix Solution is:
2
4
1.6
1
Now comes the problem I scale up the system and try to solve I get huge estimated errors. How do I resolve this. By the way I follow the same procedure of defining a dense matrix and converting them into a sparse one before solving the system. The code snippet is as follows
typedef Eigen::SparseMatrix<double> SpMat;
SpMat SparseKGl;
VectorXd wsol;
SparseKGl = KGl.sparseView();
BiCGSTAB<SparseMatrix<double> > bicg;
wsol=bicg.compute(SparseKGl).solve(ForceGl);
std::cout << "iterations: " << bicg.iterations() << std::endl;
std::cout << "estimated error: " << bicg.error() << std::endl;
// update and solve again
wsol = bicg.solve(ForceGl);
The output I get is
iterations: 22
estimated error: 70549
Can anyone please provide some insights into the same?
Regards
I have a 2 dimensional matrix with each column corresponding to one independent signal. I am going to perform N 1D fft on each column. In matlab, apply a fft to a 2D matrix will do the trick. But I am porting my code to c++ with fftw. I wonder if there is a way to do so. I try the following code by setting the column size to 1 and row size to 4 (total row number), but it does not help.
#include <iostream>
#include <complex>
#include "fftw3.h"
using namespace std;
int main(int argc, char** argv)
{
complex<double> data[4][2];
data[0][0] = complex<double>(1,1);
data[1][0] = complex<double>(2,1);
data[2][0] = complex<double>(3,1);
data[3][0] = complex<double>(4,1);
data[0][1] = complex<double>(1,1);
data[1][1] = complex<double>(1,2);
data[2][1] = complex<double>(1,3);
data[3][1] = complex<double>(1,4);
cout << "original data ..." << endl;
cout << data[0][0] << '\t' << data[0][1] << endl;
cout << data[1][0] << '\t' << data[1][1] << endl;
cout << data[2][0] << '\t' << data[2][1] << endl;
cout << data[3][0] << '\t' << data[3][1] << endl;
cout << endl << endl;
fftw_plan plan=fftw_plan_dft_2d(4, 1,(fftw_complex*)&data[0][0], (fftw_complex*)&data[0][0], FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(plan);
cout << "after fftw ..." << endl;
cout << data[0][0] << '\t' << data[0][1] << endl;
cout << data[1][0] << '\t' << data[1][1] << endl;
cout << data[2][0] << '\t' << data[2][1] << endl;
cout << data[3][0] << '\t' << data[3][1] << endl;
return 0;
}
Above code takes the first and second row and reshape them to 2x2 matrix then perform a 2D fft.
Up to now, the only way that comes to my mind is as follow. Let's say I have NxM (N rows, M columns), I create M fftw plans for M 1D fftw. I execute M fftw in serial to get the result. But in practical application, the matrix is very big, M is so large. It is very inefficient to do this way. Any better idea? Thanks.
For those stumbling across this nowadays, the FFTW devs have implemented routines for this operation, which is faster than looping through each column and taking a separate transform. You certainly don't want to take a 2D transform (as is shown in the question), which is mathematically different than row-wise 1D transforms.
The key to you question is in fftw_plan_many_dft. Here is a link to the full documentation.
Here is an example (modifed from the above link) that illustrates what you're looking for.
#include "fftw3.h"
int main() {
fftw_complex *A; // array of data
A = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*10*3);
// ...
/* Transform each column of a 2d array with 10 rows and 3 columns */
int rank = 1; /* not 2: we are computing 1d transforms */
int n[] = {10}; /* 1d transforms of length 10 */
int howmany = 3;
int idist = 1;
int odist = 1;
/* distance between two elements in the same column */
int istride = 3;
int ostride = 3;
int *inembed = n, *onembed = n;
/* forward, in-place, 1D transform of each column */
fftw_plan p;
p = fftw_plan_many_dft(rank, n, howmany, A, inembed, istride, idist, A, onembed, ostride, odist, FFTW_FORWARD, FFTW_ESTIMATE);
// ...
/* run transform */
fftw_execute_dft(p, A, A);
// ...
/* we don't want memory leaks */
fftw_destroy_plan(p);
fftw_free(A);
}
I have 2 std::vectors:
to first vector, I emplace instance
to second vector, I want to store the address of the instance just emplaced
But it does not work, i.e., the stored address differs from the emplaced instance's address.
If it matters at all, I'm on Linux and using g++ 5.1 and clang 3.6 with -std=c++11.
Here's a working example to illustrate the problem.
#include <iostream>
#include <vector>
struct Foo {
Foo(int a1, int a2) : f1(a1), f2(a2) {}
int f1;
int f2;
};
int main(int, char**) {
std::vector<Foo> vec1;
std::vector<Foo*> vec2;
int num = 10;
for (int i = 0; i < num; ++i) {
vec1.emplace_back(i, i * i);
// I want to store the address of *emplaced* instance...
vec2.push_back(&vec1.back());
}
// same
std::cout << "size 1: " << vec1.size() << std::endl;
std::cout << "size 2: " << vec2.size() << std::endl;
// same for me
std::cout << "back 1: " << &vec1.back() << std::endl;
std::cout << "back 2: " << vec2.back() << std::endl;
// typically differ ?
std::cout << "front 1: " << &vec1.front() << std::endl;
std::cout << "front 2: " << vec2.front() << std::endl;
for (int i = 0; i < num; ++i) {
std::cout << i + 1 << "th" << std::endl;
// same for last several (size % 4) for me
std::cout << "1: " << &vec1[i] << std::endl;
std::cout << "2: " << vec2[i] << std::endl;
}
}
Questions
Is it correct behavior ? I guess it's caused by storing the address of temporary instance but I want to know whether it's permitted by the standard (just curious).
If above is true, how to work around this ? I resolved this by changing first one to vector<unique_ptr<Foo>> but is there any idiomatic way ?
Two options:
1) You can simply fix your test. You just need in you test preallocate enough memory first with
vec1.reserve(10);
Well, this is implementation details for std::vector. As more and more items are added to std::vector it needs to get more space for them. And this space must be contigious. So when there is not enough space for a new element std::vector allocates a bigger block of memory, copies existing elements to it, add the new element and finally frees the block of memory that it used before. As a result addresses that you stored in vec2 might become invalid.
However, if you preallocate enough memory for 10 elements then you code is correct.
Or, since reserving memory is sort of tricky thing to do
2) use std::deque since insertion and deletion at either end of a deque never invalidates pointers or references to the rest of the elements (http://en.cppreference.com/w/cpp/container/deque) and forget about the problem with invalidated addresses. So no need to reserve memory.
I'm using eigen matrix library.
How can I convert a matrix of 1* 1 to a number(float or others)?
It's OK to do this
cout << ((MatrixXf(1,2) << 0, 2).finished()) * ((MatrixXf(2,1) << 0, 2).finished()) << endl;
But when I try to do this
MatrixXf mtemp(2,1);
mtemp(0,0) = ((MatrixXf(1,2) << 0, 2).finished()) * ((MatrixXf(2,1) << 0, 2).finished());
It said 'cannot convert const Eigen::GeneralProduct to float in assignment'.
If mat is an 1-by-1 matrix, then mat.value() is its only entry as a scalar.
Thus, you can do
mtemp(0,0) = (((MatrixXf(1,2) << 0, 2).finished())
* ((MatrixXf(2,1) << 0, 2).finished())).value();