#include #include #include using namespace std; // use rational numbers #include // use math constants #include // use math factorial #include //using namespace boost::math // // use units // #include // #include // #include // #include // #include // // using namespace boost::units; // using namespace boost::units::si; // using namespace boost::units::si::constants; // //use units end // use unlimited precision //#include // the mpz_class gives arbitrary precision. I need working factorials of 50, or even better 100! //typedef mpz_class REAL; typedef double REAL; vector> hermite_polynomial_coefficients(int order, boost::rational lambda_per_alpha) { vector> c_even; // can't use static, because lambda_per_alpha changes between calls vector> c_odd; if(c_even.size() == 0) { c_even.push_back(1); c_even.push_back(0); } if(c_odd.size() == 0) { c_odd.push_back(0); c_odd.push_back(1); } vector>& a( (order % 2 == 0) ?c_even:c_odd ); if(order+1 < a.size()) return a; for(int i = a.size() ; i <= order ; ++i) { boost::rational next = a[i-2]*(2*(i-2)+1-lambda_per_alpha)/(i*(i-1)); a.push_back(next); } // BOOST_FOREACH(boost::rational v,a) // std::cout << v << " "; // std::cout << "\n"; return a; } vector> hermite_polynomial_scaled(int order, boost::rational lambda_per_alpha) { vector> a(hermite_polynomial_coefficients(order,lambda_per_alpha)); vector> b; boost::rational factor(std::pow(2,order)/a[order]); for(int i = 0 ; i<=order ; ++i) b.push_back(a[i]*factor); return b; } // I want some results, this is not compiling, so I rewrite this without units. // // /* this function returns 1/sqrt(meter) */ quantum_wavefunction_1D quantum_oscillator_wavefunction( // int n // n - order of wavefunction // , const quantity x // position // , const quantity mass // mass - mass of particle // , const quantity omega // oscillator frequency // ) // { // typedef derived_dimension::type reciprocal_area; // // typedef derived_dimension >::type quantum_wavefunction_1D; // // quantity E ( hbar*omega*(n+0.5) ); // energy of oscillator // quantity lambda ( 2.0*mass*E / (hbar*hbar) ); // // quantity alpha ( mass*omega / hbar ); // auto alpha_root(root<2>(alpha)); // REAL lambda_per_alpha ( 2*n+1 ); // // // N_n should be 1/sqrt(meter) because it has a dimension of quantum_wavefunction_1D // auto N_n(root<2>( root<2>(alpha/constants::pi() ) /(std::pow(2,n)*factorial(n) ) )); // // complex i(0,1); // complex result(0); // vector> a(hermite_polynomial_scaled(n,lambda_per_alpha)) // for(int v=0 ; v<=n ; v++) // result+=N_n*a[v]*pow(alpha_root*x)*exp(-0.5*alpha*pow<2>(x)); // retirn result; // } // REAL quantum_oscillator_wavefunction( // assume hbar=1, mass=1, frequency=1 int n // n - order of wavefunction , REAL x // position , REAL mass=1.0 // mass - mass of particle , REAL omega=1.0 // oscillator frequency ) { REAL hbar=1.0; REAL E ( hbar*omega*(n+0.5) ); // energy of oscillator REAL lambda ( 2.0*mass*E / (hbar*hbar) ); // REAL alpha ( mass*omega / hbar ); REAL alpha_root(pow(alpha,0.5)); //REAL lambda_per_alpha ( 2*n+1 ); // N_n should be 1/sqrt(meter) because it has a dimension of quantum_wavefunction_1D REAL N_n( pow( pow(alpha/boost::math::constants::pi() , 0.5) /(std::pow(2,n)*boost::math::factorial(n) ) , 0.5) ); complex i(0,1); complex result(0); vector> a(hermite_polynomial_scaled(n, 2*n+1 )); for(int v=0 ; v<=n ; v++) { REAL a_v(boost::rational_cast(a[v])); // Hermite Polynomial coefficient result+=N_n*a_v*pow(alpha_root*x , v) *exp(-0.5*alpha*pow(x,2)); } return abs(result); } int main() { // this code is checking if Hermite Polynomials are OK // it's correct so comment it out. //for(int n=0 ; n<12 ; n++) //{ // int pot(n); // std::cout << n << " : "; // vector> a(hermite_polynomial_scaled(n,2*n+1)); // BOOST_REVERSE_FOREACH(boost::rational v,a) // { // if(v!=0) // std::cout << boost::rational_cast(v) << "*x^"<< pot << " "; // --pot; // } // std::cout << "\n"; //} // quantity s(-1*meter); // quantity ds(0.01*milli*meter); // for(quantity x=-s ; x<=s ; x+=ds) // { // cout << x << " " << quantum_oscillator_wavefunction(...) << "\n"; // } // without units, for now. REAL s=15.0; REAL ds=0.01; for(REAL x=-s ; x<=s ; x+=ds) { cout << x << " " << quantum_oscillator_wavefunction(25,x) << "\n"; } return true; }