Eigen Package Iterate over Row Major Sparse Matrix - matrix

I was trying to iterate over the non zero elements of a row major sparse matrix, such as shown below:
Eigen::SparseMatrix<double,Eigen::RowMajor> Test(2, 3);
Test.insert(0, 1) = 34;
Test.insert(1, 2) = 56;
for (int k = 0; k < Test.outerSize(); ++k){
for (Eigen::SparseMatrix<double>::InnerIterator it(Test, k); it; ++it){
cout << it.row() <<"\t";
cout << it.col() << "\t";
cout << it.value() << endl;
}
}
but I dont see the right values. Instead, I see random values for it.row(), a value of 1 for it.col() and some random value for it.value(), as shown below:
-17891602 1 -2.65698e+303
Changing RowMajor to ColumnMajor makes the code work as expected.
I am not sure what went wrong for the row major part ? Can someone please let me know what am I missing here ?
Thanks in advance

I'm surprised that it compiles fine: the type of your iterator is not correct. It must be a SparseMatrix<double,Eigen::RowMajor>::InnerIterator.

Related

Iterative multiplication of relative transforms leads to fast instability

I'm writing a program that receives Eigen transforms and stores them in a container after applying some noise. In particular, at time k, I receive transform Tk. I get from the container the transform Tk-1, create the delta = Tk-1-1 · Tk, apply some noise to delta and store Tk-1 · delta as a new element of the container.
I've noticed that after 50 iterations the values are completely wrong and at every iteration I see that the last element of the container, when pre-multiplied by its inverse, is not even equal to the identity.
I've already checked that the container follows the rules of allocation specified by Eigen.
I think the problem is related to the instability of the operations I'm doing.
The following simple code produce the nonzero values when max = 35 and goes to infinity when max is bigger than 60.
Eigen::Isometry3d my_pose = Eigen::Isometry3d::Identity();
my_pose.translate(Eigen::Vector3d::Random());
my_pose.rotate(Eigen::Quaterniond::UnitRandom());
Eigen::Isometry3d my_other_pose = my_pose;
int max = 35;
for(int i=0; i < max; i++)
{
my_pose = my_pose * my_pose.inverse() * my_pose;
}
std::cerr << my_pose.matrix() - my_other_pose.matrix() << std::endl;
I'm surprised how fast the divergence happens. Since my real program is expected to iterate more than hundreds of times, is there a way to create relative transforms that are more stable?
Yes, use a Quaterniond for the rotations:
Eigen::Isometry3d my_pose = Eigen::Isometry3d::Identity();
my_pose.translate(Eigen::Vector3d::Random());
my_pose.rotate(Eigen::Quaterniond::UnitRandom());
Eigen::Isometry3d my_other_pose = my_pose;
Eigen::Quaterniond q(my_pose.rotation());
int max = 35;
for (int i = 0; i < max; i++) {
std::cerr << q.matrix() << "\n\n";
std::cerr << my_pose.matrix() << "\n\n";
q = q * q.inverse() * q;
my_pose = my_pose * my_pose.inverse() * my_pose;
}
std::cerr << q.matrix() - Eigen::Quaterniond(my_other_pose.rotation()).matrix() << "\n";
std::cerr << my_pose.matrix() - my_other_pose.matrix() << std::endl;
If you would have examined the difference you printed out, the rotation part of the matrix gets a huge error, while the translation part is tolerable. The inverse on the rotation matrix will hit stability issues quickly, so using it directly is usually not recommended.

c++ vector sorting with row and first column

i have a 2d vector 10*100, with totally 1000 integers.
i want to sort the numbers by row and then by the first column containing every smallest number in each row after sorting by row.
then i want to find the smallest in the first column and store it in a new vector, at the same time erase this smallest num in that row, the rest numbers move forward and keep going in this way. but my code always has problems, i am a beginner, i can not fix it even after i have tried more than 20 times.
please help me out!!!
vector<int> final;
vector<int> firstcol;
for (int j=0; j<vec.size(); j++) {
firstcol.push_back(vec[j][0]);
cout << firstcol[j]<< endl;
}
int mini = *firstcol.begin();
for(int k=0; k< firstcol.size();k++){
while (firstcol[k]< mini) {
mini=firstcol[k];
final.push_back(mini);
}
vec[k].erase(vec[k].begin());
}
cout << "mini:" << mini<<endl;
for (int m=0; m< final.size(); m++) {
cout << final[m]<<endl;
}

Is fftw output depending on size of input?

In the last week i have been programming some 2-dimensional convolutions with FFTW, by passing to the frequency domain both signals, multiplying, and then coming back.
Surprisingly, I am getting the correct result only when input size is less than a fixed number!
I am posting some working code, in which i take simple initial constant matrixes of value 2 for the input, and 1 for the filter on the spatial domain. This way, the result of convolving them should be a matrix of the average of the first matrix values, i.e., 2, since it is constant. This is the output when I vary the sizes of width and height from 0 to h=215, w=215 respectively; If I set h=216, w=216, or greater, then the output gets corrupted!! I would really appreciate some clues about where could I be making some mistake. Thank you very much!
#include <fftw3.h>
int main(int argc, char* argv[]) {
int h=215, w=215;
//Input and 1 filter are declared and initialized here
float *in = (float*) fftwf_malloc(sizeof(float)*w*h);
float *identity = (float*) fftwf_malloc(sizeof(float)*w*h);
for(int i=0;i<w*h;i++){
in[i]=5;
identity[i]=1;
}
//Declare two forward plans and one backward
fftwf_plan plan1, plan2, plan3;
//Allocate for complex output of both transforms
fftwf_complex *inTrans = (fftwf_complex*) fftw_malloc(sizeof(fftwf_complex)*h*(w/2+1));
fftwf_complex *identityTrans = (fftwf_complex*) fftw_malloc(sizeof(fftwf_complex)*h*(w/2+1));
//Initialize forward plans
plan1 = fftwf_plan_dft_r2c_2d(h, w, in, inTrans, FFTW_ESTIMATE);
plan2 = fftwf_plan_dft_r2c_2d(h, w, identity, identityTrans, FFTW_ESTIMATE);
//Execute them
fftwf_execute(plan1);
fftwf_execute(plan2);
//Multiply in frequency domain. Theoretically, no need to multiply imaginary parts; since signals are real and symmetric
//their transform are also real, identityTrans[i][i] = 0, but i leave here this for more generic implementation.
for(int i=0; i<(w/2+1)*h; i++){
inTrans[i][0] = inTrans[i][0]*identityTrans[i][0] - inTrans[i][1]*identityTrans[i][1];
inTrans[i][1] = inTrans[i][0]*identityTrans[i][1] + inTrans[i][1]*identityTrans[i][0];
}
//Execute inverse transform, store result in identity, where identity filter lied.
plan3 = fftwf_plan_dft_c2r_2d(h, w, inTrans, identity, FFTW_ESTIMATE);
fftwf_execute(plan3);
//Output first results of convolution(in, identity) to see if they are the average of in.
for(int i=0;i<h/h+4;i++){
for(int j=0;j<w/w+4;j++){
std::cout<<"After convolution, component (" << i <<","<< j << ") is " << identity[j+i*w]/(w*h*w*h) << endl;
}
}std::cout<<endl;
//Compute average of data
float sum=0.0;
for(int i=0; i<w*h;i++)
sum+=in[i];
std::cout<<"Mean of input was " << (float)sum/(w*h) << endl;
std::cout<< endl;
fftwf_destroy_plan(plan1);
fftwf_destroy_plan(plan2);
fftwf_destroy_plan(plan3);
return 0;
}
Your problem has nothing to do with fftw ! It comes from this line :
std::cout<<"After convolution, component (" << i <<","<< j << ") is " << identity[j+i*w]/(w*h*w*h) << endl;
if w=216 and h=216 then `w*h*w*h=2 176 782 336. The higher limit for signed 32bit integer is 2 147 483 647. You are facing an overflow...
Solution is to cast the denominator to float.
std::cout<<"After convolution, component (" << i <<","<< j << ") is " << identity[j+i*w]/(((float)w)*h*w*h) << endl;
The next trouble that you are going to face is this one :
float sum=0.0;
for(int i=0; i<w*h;i++)
sum+=in[i];
Remember that a float has 7 useful decimal digits. If w=h=4000, the computed average will be lower than the real one. Use a double or write two loops and sum on the inner loop (localsum) before summing the outer loop (sum+=localsum) !
Bye,
Francis

Range-based for loop with boost::adaptor::indexed

The C++11 range-based for loop dereferences the iterator. Does that mean that it makes no sense to use it with boost::adaptors::indexed? Example:
boost::counting_range numbers(10,20);
for(auto i : numbers | indexed(0)) {
cout << "number = " i
/* << " | index = " << i.index() */ // i is an integer!
<< "\n";
}
I can always use a counter but I like indexed iterators.
Is it possible to use them somehow with range-based for loops?
What is the idiom for using range-based loops with an index? (just a plain counter?)
This was fixed in Boost 1.56 (released August 2014); the element is indirected behind a value_type with index() and value() member functions.
Example: http://coliru.stacked-crooked.com/a/e95bdff0a9d371ea
auto numbers = boost::counting_range(10, 20);
for (auto i : numbers | boost::adaptors::indexed())
std::cout << "number = " << i.value()
<< " | index = " << i.index() << "\n";
It seems more useful when iterating over collection, where you may need the index position (to print the item number if not for anything else):
#include <boost/range/adaptors.hpp>
std::vector<std::string> list = {"boost", "adaptors", "are", "great"};
for (auto v: list | boost::adaptors::indexed(0)) {
printf("%ld: %s\n", v.index(), v.value().c_str());
}
Prints:
0: boost
1: adaptors
2: are
3: great
Any innovation for simply iterating over integer range is strongly challenged by the classic for loop, still very strong competitor:
for (int a = 10; a < 20; a++)
While this can be twisted up in a number of ways, it is not so easy to propose something that is obviously much more readable.
The short answer (as everyone in the comments mentioned) is "right, it makes no sense." I have also found this annoying. Depending your programming style, you might like the "zipfor" package I wrote (just a header): from github
It allows syntax like
std::vector v;
zipfor(x,i eachin v, icounter) {
// use x as deferenced element of x
// and i as index
}
Unfortunately, I cannot figure a way to use the ranged-based for syntax and have to resort to the "zipfor" macro :(
The header was originally designed for things like
std::vector v,w;
zipfor(x,y eachin v,w) {
// x is element of v
// y is element of w (both iterated in parallel)
}
and
std::map m;
mapfor(k,v eachin m)
// k is key and v is value of pair in m
My tests on g++4.8 with full optimizations shows that the resulting code is no slower than writing it by hand.

Ternary search recursion isn't correct

I learned about ternary search from Wikipedia. I'm not sure what they mean by the parameter absolute precision. They didn't elaborate. But here is the pseudocode:
def ternarySearch(f, left, right, absolutePrecision):
#left and right are the current bounds; the maximum is between them
if (right - left) < absolutePrecision:
return (left + right)/2
leftThird = (2*left + right)/3
rightThird = (left + 2*right)/3
if f(leftThird) < f(rightThird):
return ternarySearch(f, leftThird, right, absolutePrecision)
return ternarySearch(f, left, rightThird, absolutePrecision)
I want to find max value from a unimodal function. That means I want to print the border point of the increasing and decreasing sequence. If the sequence is
1 2 3 4 5 -1 -2 -3 -4
then I want to print 5 as output.
Here is my attempt. It isn't giving output. Can you please help or give me link that contains good tutorial on ternary search for self learning?
#include<iostream>
using namespace std;
int ternary_search(int[], int, int, int);
int precval = 1;
int main()
{
int n, arr[100], target;
cout << "\t\t\tTernary Search\n\n" << endl;
//cout << "This program will find max element in an unidomal array." << endl;
cout << "How many integers: ";
cin >> n;
for (int i=0; i<n; i++)
cin >> arr[i];
cout << endl << "The max number in the array is: ";
int res = ternary_search(arr,0,n-1,precval)+0;
cout << res << endl;
return 0;
}
int ternary_search(int arr[], int left, int right, int precval)
{
if (right-left <= precval)
return (arr[right] > arr[left]) ? arr[right] : arr[left];
int first_third = (left * 2 + right) / 3;
int last_third = (left + right * 2) / 3;
if(arr[first_third] < arr[last_third])
return ternary_search(arr, first_third, right, precval);
else
return ternary_search(arr, left, last_third, precval);
}
Thank you in advance.
Absolute precision means the maximum error between the returned result and the true result i.e. max | returned_result - true_result |. In that context, f is a continuous function.
Since you are looking at a discrete function, you can't do much better than get to the point where right - left <= 1. Then, just compare the two resultant values and return the value corresponding to the larger one (since you're looking for max).
EDIT
The first partition point, being mathematically 2/3*left + right/3, should be discretized to ceil(2/3*left + right/3) (so that the relationship is left < first_third <= last_third < right
So first_third = (left*2+right)/3 should be changed to first_third = (left*2 + right + 2)/3.
Try Golden Section search (or Fibonacci search for discrete functions).
It has a smaller number of recursions AND a 50% reduction in evaluations of f, compared to the above ternary search.

Resources