I need to compute some determinants for a project: I use c++ 14 and Eigen.
So, MatrixXd A is a Eigen matrix with X rows and X cols and contains double values. To compute determinant I use A.determinant(). Let's pretend that A.determinant() is equal to d. Then, the problem apper when I use QR decomposition because R.determinant() is equal to -d, should be equal to d. This happened only for large matrices (with size greater than 5 - I observed this). Only the sign is problem, why?
My code:
#include <iostream>
#include <Eigen>
#include <fstream>
#include <chrono>
using namespace Eigen;
using namespace std;
using namespace std::chrono;
ifstream fin("input.txt");
int main()
{
double aux;
int n = 10;
MatrixXd A;
A.resize(n,n);
// Read A
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
fin>>aux;
A(i,j) = aux;
}
cout<<"Start!"<<endl;
cout<<A.determinant()<<endl;
//Use QR decomposition, get R matrix
HouseholderQR<MatrixXd> qr(A);
qr.compute(A);
MatrixXd R = qr.matrixQR().template triangularView<Upper>();
// R is a triangular matrix, det(A) should be equal to det(R)
cout<<R.determinant()<<endl;
return 0;
}
How can I solve this?
img
Related
How to create a dynamic 3d matrix using the Eigen library. and how can slice the particular channel, in that channel slice some height and width?
example:
I want to create a matrix of size 3 * 320 * 240 (here channel width and height known at runtime), and then select a slice of 3 * 3 in each channel.
Perhaps something like this:
#include <iostream>
#include <vector>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
int a = 320;
int b = 240;
// Create as many as you want, probably better in a loop.
MatrixXd m(a, b);
MatrixXd n(a, b);
MatrixXd o(a, b);
std::vector<MatrixXd> v;
v.push_back(m);
v.push_back(n);
v.push_back(o);
std::cout << v.at(0)(0, 1) << std::endl;
}
I am learning to use a c++ library to perform non-uniform FFT (NUFFT). The library provides 3 types of NUFFT.
Type 1: forward transform from a non-uniform x grid to a uniform k-space grid.
Type 2: backward transform from a uniform k-space grid to a non-uniform x grid
Type 3: from non-uniform to non-uniform
I tested the library in 1D by performing NUFFT on a test function sin(x) from -pi to pi using Type1 NUFFT, transform it back using Type2 NUFFT, and compare the output with sin(x). At first, I tested it on a uniform x grid, which shows a very small error. The error unfortunately is very large when the test is done on a non-uniform x grid.
Two possibilities:
My implementation of NUFFT is incorrect, but the implementation is rather simple, so I doubt if this is the case.
The author mentions that Type2 is NOT the inverse of Type1, so I believe that might be the problem. Since I am not an expert in NUFFT, I wonder if there is an alternative way to perform a forward/backward test with NUFFT?
My purpose is to develop a FFT Poisson solver on a irregular mesh, so I need to perform NUFFT forward and backward, and therefore important to overcome this problem. Besides using FINUFFT, any other suggestion is also welcome.
Thank you for reading.
The code is here for those who is interested.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex>
#include <fftw3.h>
#include <functional>
#include "finufft/src/finufft.h"
using namespace std;
int main()
{
double pi = 3.14159265359;
int N = 128*2;
int i;
double X[N];
double L = 2*pi;
double dx = L/(N);
nufft_opts opts; finufft_default_opts(&opts);
complex<double> R = complex<double>(1.0,0.0); // the real unit
complex<double> in1[N], out1[N], out2[N];
for(i = 0; i < N; i++) {
//X[i] = -(L/2) + i*dx ; // uniform grid
X[i] = -(L/2) + pow(double(i)/N,7.0)*L; //non-uniform grid
in1[i] = sin(X[i])*R ;}
int ier = finufft1d1(N,X,in1,-1,1e-10,N,out1,opts); // type-1 NUFFT
int ier2 = finufft1d2(N,X,out2,+1,1e-10,N,out1,opts); // type-2 NUFFT
// checking the error
double erl1 = 0.;
for ( i = 0; i < N; i++) {
erl1 += fabs( in1[i].real() - out2[i].real()/(N))*dx;
}
std::cout<< erl1 <<" " << ier << " "<< ier2<< std::endl ; // error
return 0;
}
For some reason, the developer made an update on their page which answers exactly my question. https://finufft.readthedocs.io/en/latest/examples.html#periodic-poisson-solve-on-non-cartesian-quadrature-grid. In brief, their NUFFT code is NOT good in the case of fully adaptive scheme, but I would still provide an answer and code here for completeness.
There are two ingredients missing in my code.
(1) I need to multiply the function, sin(x), with a weight before using NUFFT. The weight comes from the determinant of the Jacobian in their 2D example, so the weight is simply the derivative the of the nonuniform coordinate with respect to the uniform coordinate dx/dksi for a 1D example.
(2) Nk must be smaller than N.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex>
#include <fftw3.h>
#include <functional>
#include "finufft/src/finufft.h"
using namespace std;
int main()
{
double pi = 3.14159265359;
int N = 128*2;
int Nk = 32; // smaller than N
int i;
double X[N];
double L = 2*pi;
double dx = L/(N);
nufft_opts opts; finufft_default_opts(&opts);
complex<double> R = complex<double>(1.0,0.0); // the real unit
complex<double> in1[N], out1[N], out2[N];
for(i = 0; i < N; i++) {
ksi[i] = -(L/2) + i*dx ; //uniform grid
X[i] = -(L/2) + pow(double(i)/(N-1),6)*L; //nonuniform grid
}
dX = der(ksi,X,1); // your own derivative code
for(i = 0; i < N; i++) {
in1[i] = sin(X[i]) * dX[i] * R ; // applying weight
}
int ier = finufft1d1(N,X,in1,-1,1e-10,Nk,out1,opts); // type-1 NUFFT
int ier2 = finufft1d2(N,X,out2,+1,1e-10,Nk,out1,opts); // type-2 NUFFT
// checking the error
double erl1 = 0.;
for ( i = 0; i < N; i++) {
erl1 += fabs( in1[i].real() - out2[i].real()/(N))*dx;
}
std::cout<< erl1 <<" " << ier << " "<< ier2<< std::endl ; // error
return 0;
}
so I created a program that takes in two long double numbers and some a particular form of calculation on them. but the issue is, the output for me is inf or in some compilers, 0..
So the error only occurs when I enter exponential values like say I enter 1.11224e+2121 1.11224e+2121
then I get inf or 0 but if I get something like 2.4 5.9 I get proper value. How do I fix this?
here is my code
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int main()
{
long double a,b,add=0,mean=0;
cin>>a>>b;
vector<long double> vector;
vector.push_back(a);
vector.push_back(b);
mean=(vector[0]+vector[1])/2;
for (int k = 0; k < 2; k++)
{
add= add+ pow((vector[k] - mean), 2);
}
cout<<add/2;
return 0;
}
I have learnt how to find inverse of a matrix using Eigen. But when I'm finding inverse of an array that is a output of function I got an error
request for member ‘inverse’ in ‘x’, which is of non-class type
‘double**’
Please help me out, in using c++ library to find inverse of a matrix.
The code I have written is:
#include <iostream>
#include <armadillo>
#include <cmath>
#include <Eigen/Dense>
using namespace std;
using namespace arma;
using namespace Eigen;
int main()
{
vec a;
double ** x;
double ** inv_x;
a <<0 << 1 << 2 << 3 << 4; //input vector to function
double ** f (vec a); //function declaration
x= f(a); // function call
//inv_x=inv(x);
cout << "The inverse of x is:\n" << x.inverse() << endl; // eigen command to find inverse
return 0;
}
// function definition
double ** f(vec a)
{
double ** b = 0;
int h=5;
for(int i1=0;i1<h;i1++)
{
b[i1] = new double[h];
{
b[i1][0]=1;
b[i1][1]=a[i1];
b[i1][2]=a[i1]*a[i1]+1/12;
b[i1][3]=pow(a[i1],3)+a[i1]/4;
b[i1][4]=1/80+pow(a[i1],2)/2+pow(a[i1],4);
}
}
return b;
}
Here user defined function f return an array x. I'm trying to find inverse of x using eigen library.
First, as mentioned by Martin Bonner, don't use double** to store a matrix, but make sure the coefficients are sequentially stored.
Then, you can use the Eigen::Map class to see a raw buffer as an Eigen's object, as documented there. For instance:
double data[2][2];
Eigen::Map<Matrix<double,2,2,RowMajor> > mat(data[0]);
mat = mat.inverse();
I have a small script for manipulating a sparse matrix in C++. It works perfectly fine except taking too much time. Since I'm doing this manipulation over and over, it is critical to speed it up. I appreciate any idea.Thanks
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <iostream> /* cout, fixed, scientific */
#include <string>
#include <cmath>
#include <vector>
#include <list>
#include <string>
#include <sstream> /* SJW 08/09/2010 */
#include <fstream>
#include <Eigen/Dense>
#include <Eigen/Sparse>
using namespace Eigen;
using namespace std;
SparseMatrix<double> MatMaker (int n1, int n2, double prob)
{
MatrixXd A = (MatrixXd::Random(n1, n2) + MatrixXd::Ones(n1, n2))/2;
A = (A.array() > prob).select(0, A);
return A.sparseView();
}
////////////////This needs to be optimized/////////////////////
int SD_func(SparseMatrix<double> &W, VectorXd &STvec, SparseMatrix<double> &Wo, int tauR, int tauD)
{
W = W + 1/tauR*(Wo - W);
for (int k = 0; k < W.outerSize(); ++k)
for (SparseMatrix<double>::InnerIterator it(W, k); it; ++it)
W.coeffRef(it.row(),it.col()) = it.value() * (1-STvec(it.col())/tauD);
return 1;
}
int main ()
{
SparseMatrix<double> Wo = MatMaker(5000, 5000, 0.1);
SparseMatrix<double> W = MatMaker(5000, 5000, 0.1);
VectorXd STvec = VectorXd::Random(5000);
clock_t tsd1,tsd2;
float Timesd = 0.0;
tsd1 = clock();
///////////////////////////////// Any way to speed up this function???????
SD_func(W, STvec, Wo, 8000, 50);
//////////////////////////////// ??????????
tsd2 = clock();
Timesd += (tsd2 - tsd1);
cout<<"SD time: " << Timesd / CLOCKS_PER_SEC << " s" << endl;
return 0;
}
The most critical performance improvement (IMO) you can make is to not use W.coeffRef(it.row(),it.col()). It performs a binary search in W for the element each time. As you are already using SparseMatrix<double>::InnerIterator it(W, k); it is very simple to change your function to skip the binary search:
int SD_func_2(SparseMatrix<double> &W, VectorXd &STvec, SparseMatrix<double> &Wo, int tauR, int tauD)
{
W = W + 1/tauR*(Wo - W);
double tauDInv = 1./tauD;
for (int k = 0; k < W.outerSize(); ++k)
for (SparseMatrix<double>::InnerIterator it(W, k); it; ++it)
it.valueRef() *= (1-STvec(it.col())*tauDInv);
return 1;
}
This results in a roughly x3 speedup. Note that I've incorporated #dshin's comment that multiplying is faster than division, however the performance improvement is about 90% removing the binary search, 10% multiplication vs. division.