SSE value calculated in C++ eigen is different from true value - c++

I am a beginner of C++. Any help will be very appreciated!
I can successfully compile and run the following code:
#include <Eigen/Dense>
#include <iostream>
#include <cmath>
using namespace Eigen;
int main()
{
MatrixXf m1(10,1);
m1 << 50,51,52,54,53,60,59,65,67,70;
MatrixXf m3(3,10);
MatrixXf m2(10,3);
m3<< 1,1,1,1,1,1,1,1,1,1, //Xf[,5:6]
54,61,52,70,63,0,0,0,0,0,
0,0,0,0,0,79,68,65,79,76;
m2 << m3.transpose();
MatrixXf I(10,10);
I.setIdentity(10,10);
float SSE =(m1.transpose()*(I-m2*(m2.transpose()*m2).inverse()*m2.transpose())*m1).determinant();
std::cout << "SSE=" << std::endl;
std::cout << SSE << std::endl << std::endl;
system("pause");
}
SSE worked out in C++:87.7938,while SSE true value:88.29133

You need to use MatrixXd instead of MatrixXf

Related

How to cout int like a double

I'd like to display some integer with currency index (I mean dot and double zero)
For example like here:
#include <iostream>
int main() {
int w1=700,c1=99,c2=98;
double noh2o=w1*(100.0-c1)/100.0;
double w2=noh2o+noh2o/(100.0-c2)*c2;
std::cout<<w2<<std::endl;
}
If somebody can help me I will be thankful.
You are supposed to do it with the locale library.
Mostly copied from https://en.cppreference.com/w/cpp/io/manip/put_money like so:
#include <iomanip>
#include <iostream>
#include <locale>
int main() {
long double val = 239.9;
std::cout.imbue(std::locale("en_US.UTF-8"));
std::cout << std::showbase
<< "en_US: " << std::put_money(val)
<< std::endl;
return 0;
}
Use std::fixed and std::setprecision.
Try it online!
#include <iostream>
#include <iomanip>
int main() {
int w1=700,c1=99,c2=98;
double noh2o=w1*(100.0-c1)/100.0;
double w2=noh2o+noh2o/(100.0-c2)*c2;
std::cout << std::fixed << std::setprecision(2) << w2 << std::endl;
}
Output:
350.00

C++ double to hex console output need help in resolving

my code:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double A = 100.35;
cout.precision(0);
cout << std::hexfloat << std::fixed << std::left << A << endl;
return 0;
}
Current output:
100
my expected output:
x64
Explanation:
I want to print the hex value of decimal part of double. But I have been unsuccessful in getting this. need help. Any help in this direction will be appreciated.
What you're asking for is simply not possible. std::hex (the output you're looking for) only works for integral arguments, and std::hexfloat uses an undesirable format. You need to cast or round.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
double A = 100.35;
cout.precision(0);
cout << std::hex << std::showbase << std::lround(A) << endl;
return 0;
}

viennacl with complex numbers

I'm using viennacl to solve a linear system of equations (AX = B) with the graphic card. Also, the code uses armadillo.
My system of equations have complex numbers. So the question is: Can I solve a system of equations (with complex numbers) using viennacl?
Above is an example of a working code with real numbers.
// System headers
#include <iostream>
// Armadillo headers (disable BLAS and LAPACK to avoid linking issues)
#define ARMA_DONT_USE_BLAS
#define ARMA_DONT_USE_LAPACK
#include <armadillo>
#include <complex>
#define VIENNACL_WITH_ARMADILLO 1
// ViennaCL headers
#include "viennacl/linalg/cg.hpp"
#include "viennacl/linalg/bicgstab.hpp"
#include "viennacl/linalg/gmres.hpp"
#include "viennacl/io/matrix_market.hpp"
#include "vector-io.hpp"
//using namespace arma;
using namespace viennacl::linalg;
using namespace std;
typedef arma::mat armat;
typedef arma::vec arvec;
typedef complex<double> dcmplx;
int main(void)
{
int N = 500;
armat A(N,N);
A.randu();
arvec B(N);
B.randu();
arvec X(N);
arvec residual(N);
viennacl::matrix<double> vcl_A(N, N);
viennacl::vector<double> vcl_B(N);
viennacl::vector<double> vcl_X(N);
viennacl::vector<double> vcl_result(N);
viennacl::copy(A, vcl_A);
viennacl::copy(B, vcl_B);
viennacl::copy(X, vcl_X);
std::cout << "----- Running GMRES -----" << std::endl;
vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::gmres_tag());
viennacl::copy(vcl_A, A);
viennacl::copy(vcl_B, B);
viennacl::copy(vcl_X, X);
residual = A * X - B;
cout << "Relative residual: " << norm(residual) / norm(B) << endl;
}
Complex version of the code:
#include <iostream>
// Armadillo headers (disable BLAS and LAPACK to avoid linking issues)
#define ARMA_DONT_USE_BLAS
#define ARMA_DONT_USE_LAPACK
#include <armadillo>
#include <complex>
#define VIENNACL_WITH_ARMADILLO 1
// ViennaCL headers
#include "viennacl/linalg/cg.hpp"
#include "viennacl/linalg/bicgstab.hpp"
#include "viennacl/linalg/gmres.hpp"
#include "viennacl/io/matrix_market.hpp"
#include "vector-io.hpp"
//using namespace arma;
using namespace viennacl::linalg;
using namespace std;
typedef arma::cx_mat armat;
typedef arma::cx_vec arvec;
typedef complex<double> dcmplx;
int main(void)
{
int N = 500;
armat A(N,N);
A.randu();
arvec B(N);
B.randu();
arvec X(N);
arvec residual(N);
viennacl::matrix<dcmplx> vcl_A(N, N);
viennacl::vector<dcmplx> vcl_B(N);
viennacl::vector<dcmplx> vcl_X(N);
viennacl::vector<dcmplx> vcl_result(N);
viennacl::copy(A, vcl_A);
viennacl::copy(B, vcl_B);
viennacl::copy(X, vcl_X);
std::cout << "----- Running GMRES -----" << std::endl;
vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::gmres_tag());
viennacl::copy(vcl_A, A);
viennacl::copy(vcl_B, B);
viennacl::copy(vcl_X, X);
residual = A * X - B;
cout << "Relative residual: " << norm(residual) / norm(B) << endl;
std::cout << "----- Running BiCGStab -----" << std::endl;
vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::bicgstab_tag());
viennacl::copy(vcl_A, A);
viennacl::copy(vcl_B, B);
viennacl::copy(vcl_X, X);
residual = A * X - B;
cout << "Relative residual: " << norm(residual) / norm(B) << endl;
std::cout << "----- Running CG -----" << std::endl;
vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::cg_tag());
viennacl::copy(vcl_A, A);
viennacl::copy(vcl_B, B);
viennacl::copy(vcl_X, X);
residual = A * X - B;
cout << "Relative residual: " << norm(residual) / norm(B) << endl;
}
ViennaCL currently does not support complex numbers. The primary technical reason is that OpenCL does not natively provide support for complex numbers. While emulating complex arithmetic via real arithmetic is certainly possible, we were reluctant to go down this path and (wrongly?) hoped that a standardization for complex will come soon.

.dot() product for VectorXcd in Eigen c++

I'm trying to figure out if this is a bug in Eigen or something I'm doing wrong. I simply want the dot product of two complex vectors [ 1 , i] and [1 , -i]. The answer is 1*1 + i*(-i) = 2. But Eigen gives zero as answer. See code below:
#include <iostream>
#include <sstream>
#include <vector>
#include <fstream>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <map>
#include <sys/sysinfo.h>
#include <algorithm>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main( void ){
VectorXcd xd0(2);
complex<double> c_i( 0.0 , 1.0 );
xd0[0] = 1.0 ;
xd0[1] = c_i;
VectorXcd xd0conj = xd0.conjugate();
cout <<" vec is \n" << xd0 <<endl;
cout <<" conj vec is \n" << xd0conj <<endl;
cout << "eigen dot = " << (xd0conj).dot(xd0 ) <<endl;
complex<double> outVal = 0.0;
for( int a=0; a<xd0.size(); a++){
outVal += xd0[a]*xd0conj[a];
}
cout << "naive dot = " << outVal<<endl;
};
From the documentation:
"
If the scalar type is complex numbers, then this function returns the hermitian (sesquilinear) dot product, conjugate-linear in the first variable and linear in the second variable.
"
This product is often used, for example in quantum mechanics.
It computes conj(x)*y which is what you are seeing. I guess you want the simple / ordinary dot:
cout << "eigen dot = " << xd0conj.transpose()*xd0 <<endl;
This outputs
eigen dot = (2,0)

My function does not modify its inputs

I'm trying to learn C++ and have this small beginner question:
why does the standardize function not modify its inputs?
To help with the answers, I have posted an executing code at Coliru
here
and the sources of my program below.
Referring to the code, the question would be: why isn't what's
printed after outside the same as what's printed after inside?
#include <cstdlib>
#include <ctime>
#include <algorithm> // std::copy
#include <iostream>
using namespace std;
void standardize(const int n,const float x[],float ave,float sct){
float acc=0.0f,sum=0.0f;
sum=std::accumulate(x,x+n,0.0f);
ave=sum/(float)n;
std::for_each(x,x+n,[&](const float d){acc+=(d-ave)*(d-ave);});
sct=std::sqrt(acc/(float)(n-1));
std::cout << "inside" << std::endl;
std::cout << ave << std::endl;
std::cout << sct << std::endl;
return;
}
int main(){
const int n=1024;
float a2[n];
float part0=0.0f,part1=0.0f;
std::srand(std::time(0));
for(int i=0;i<n;i++) a2[i]=std::rand()/(float)RAND_MAX;
standardize(n,a2,part0,part1);
std::cout << "outside" << std::endl;
std::cout << part0 << std::endl;
std::cout << part1 << std::endl;
}
You are passing ave and sct by values. Your standardize method modifies copies of those arguments, letting unchanged the original ones declared in main()
Consider passing them by reference:
void standardize(const int n,const float x[],float& ave,float& sct)