In order to increase the accuracy, I have been trying to upgrade a program from double to long double. However, I got the following error.
haread.cpp:178:43: error: no match for ‘operator*’ in ‘2.0e+0 * std::operator+ [with _Tp = long double](((((const std::complex)KEp) + ((long unsigned int)(((long unsigned int)i) * 32ul)))), ((const std::complex)(& energia)
The line was
phicheb[1][i] = (2.0*(KEp[i] + energia)/dE)-phistate[is][i] ;
The arrays were dynamically defines using 'new'. All the variables are long double. The problem was obtained for all the cases when some number is multiplying the complex array. So, I changed 2.0 to 2.0L and all the similar cases. So, now the compilation is successful. However, my program does not work properly anymore. Do I need to suffix L all the long doubles that I have defined? I have defined them as follows:
long double xmin = 1.6 ; long double xmax = 7.0 ;
I am not even sure from where to start. Any suggestions? The compiler is gcc version 4.6.2 (SUSE Linux). EDIT:
for ( int is = 0 ; is < nstates ; is++ ){
for ( int i = 0 ; i < xgrid ; i++ ) phi[i] = phistate[is][i];
fft(&phi[0], &kphi[0], -1);
for ( int i = 0 ; i < xgrid ; i++ ){
kphi[i] = akx2[i]*kphi[i]*ixgrid; //calculates the KE using Fourier transform
}
fft(&kphi[0],&KEp[0],1);
for ( int i = 0 ; i < xgrid ; i++ ){
x = xmin + (i*dx) ;
energia = complex<long double>(0.0,0.0);
energia = hmatrix[is][is][i]*phistate[is][i] ; //Potential energy
phicheb[0][i] = phistate[is][i];
phicheb[1][i] = (2.0L*(KEp[i] + energia)/dE)-phistate[is][i] ;
}
for ( int j = 2 ; j < ncheb ; j++ ){ //this is a recursion relation
for ( int i = 0 ; i < xgrid ; i++ ) phi[i] = phicheb[j-1][i];
fft(&phi[0], &kphi[0], -1);
for ( int i = 0 ; i < xgrid ; i++ ){
kphi[i] = akx2[i]*kphi[i]*ixgrid;
}
fft(&kphi[0],&KEp[0],1) ;
for ( int i = 0 ; i < xgrid ; i++ ){
x = xmin + (i*dx) ;
energia = complex<long double>(0.0,0.0);
energia = hmatrix[is][is][i]*phi[i];
phicheb[j][i] = (2.0L*((2.0L*(KEp[i] + energia)/dE) - phicheb[j-1][i])) - phicheb[j-2][i]; //recursion
}
}
for ( int i = 0 ; i < xgrid ; i++){
for ( int j = 0 ; j < ncheb ; j++ ){
phistate_new[is][i] += chebc[j]*phicheb[j][i] ;
}
}
}
This is the core of the code. It is used for the propagation of wavefuction on a grid. I will try to explain the code as less technical as possible. I have the values of phistate[0][i], which is the wavefunction corresponding to a ground state (the rest of the states are all zero). Then I calculate the energy of the system (the Kinetic Energy using Fourier transform and the Potential Energy is already given). Now, using a particular method (the Chebychev method), I propagate the wavefunction in time. This method is based on a recursion relation. In this recursion, the propagation is calculated using a polynomial expansion. Chebc are long double coefficients, the values of which are well defined. All the variables whose definition are not shown, are long double.
When I use just double instead of long double, I have no problem getting results. When using long double, phistate_new, my result, has all it's values given by NaN.
long double
anddouble
can be the same accuracy. I would check they are different in your compiler first. - Neil Kirk