Skip to main content
Code Review

Return to Answer

There's no need for me to complete this review now
Source Link
Toby Speight
  • 87.7k
  • 14
  • 104
  • 325

(This is an incomplete answer - Real Life has called me away. I willwas intending to return with additional review later, but Edward has written an answer much better than this one was ever going to be.)

(This is an incomplete answer - Real Life has called me away. I will return with additional review later.)

(This is an incomplete answer - Real Life called me away. I was intending to return with additional review, but Edward has written an answer much better than this one was ever going to be.)

Added a bit more review
Source Link
Toby Speight
  • 87.7k
  • 14
  • 104
  • 325

I think you want to turn this the other way around:

wave_function::wave_function()
 : wave_function(false)
{}
wave_function::wave_function(bool init) {
 if (init) {
 // "true" setup
 }
 else {
 // "false" setup
 }
}

The population of the initial values is hard to read, and repeats a lot of calculations. These can be avoided with the judicious use of temporary variables for the intermediate results. I believe the following is equivalent to your initialization loop:

 for (int l = 0; l < grid_point; l++) {
 value[l].resize(grid_point);
 for (int m = 0; m < grid_point; m++) {
 auto const rl = real_space(l);
 auto const rm = real_space(m);
 auto const k1 = M * omega1 / PI / h_bar;
 auto const k2 = M * omega2 / PI / h_bar;
 auto const e1 = std::exp(-M*omega1*rl*rl/h_bar/2);
 auto const e2 = std::exp(-M*omega2*rm*rm/h_bar/2);
 auto const psi00 = std::pow(k1*k2, .25) * e1 * e2;
 auto const psi10 = psi00 * std::sqrt(2*M*omega1/h_bar) * rl;
 value[l][m] = psi00+psi10;
 }
 }

I've used the identity pow(x,n)*pow(y,n) == pow(x*y,n) in a couple of places above, to reduce the number of calls.

I think you want to turn this the other way around:

wave_function::wave_function()
 : wave_function(false)
{}
wave_function::wave_function(bool init) {
 if (init) {
 // "true" setup
 }
 else {
 // "false" setup
 }
}

The population of the initial values is hard to read, and repeats a lot of calculations. These can be avoided with the judicious use of temporary variables for the intermediate results. I believe the following is equivalent to your initialization loop:

 for (int l = 0; l < grid_point; l++) {
 value[l].resize(grid_point);
 for (int m = 0; m < grid_point; m++) {
 auto const rl = real_space(l);
 auto const rm = real_space(m);
 auto const k1 = M * omega1 / PI / h_bar;
 auto const k2 = M * omega2 / PI / h_bar;
 auto const e1 = std::exp(-M*omega1*rl*rl/h_bar/2);
 auto const e2 = std::exp(-M*omega2*rm*rm/h_bar/2);
 auto const psi00 = std::pow(k1*k2, .25) * e1 * e2;
 auto const psi10 = psi00 * std::sqrt(2*M*omega1/h_bar) * rl;
 value[l][m] = psi00+psi10;
 }
 }

I've used the identity pow(x,n)*pow(y,n) == pow(x*y,n) in a couple of places above, to reduce the number of calls.

Source Link
Toby Speight
  • 87.7k
  • 14
  • 104
  • 325

First, you should fix these compiler warnings:

157094.cpp: In constructor ‘wave_function::wave_function()’:
157094.cpp:53:1: warning: ‘wave_function::value’ should be initialized in the member initialization list [-Weffc++]
 wave_function::wave_function() {
 ^~~~~~~~~~~~~
157094.cpp: In constructor ‘wave_function::wave_function(bool)’:
157094.cpp:63:1: warning: ‘wave_function::value’ should be initialized in the member initialization list [-Weffc++]
 wave_function::wave_function(bool init) {
 ^~~~~~~~~~~~~
157094.cpp: In member function ‘void wave_function::alpha_beta_solver(wave_function&, compx, std::vector<std::complex<double> >&, compx, std::vector<std::complex<double> >&, int, char)’:
157094.cpp:119:54: warning: unused parameter ‘New’ [-Wunused-parameter]
 void wave_function::alpha_beta_solver(wave_function &New, compx b4_mid, std::vector<compx> &mid, compx post_mid, std::vector<compx> &R, int coor, char x_or_y) {
 ^~~
157094.cpp: In function ‘int main()’:
157094.cpp:249:10: warning: unused variable ‘check’ [-Wunused-variable]
 double check = 0.0;
 ^~~~~
157094.cpp: In member function ‘compx wave_function::sec_space_deriv(char, int, int)’:
157094.cpp:205:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

I'd advise that you use real, strongly-typed constants in preference to preprocessor substitution:

const double hbar{1};
const double L{0.5};
// etc.
const compx I{0,1};
// No need for complex values of 1 or 2, as doubles will promote okay

The following code doesn't do what you think it does:

wave_function::wave_function(bool init) {
 if (init) {
 // (snip)
 }
 else if (!init) {
 wave_function();
 }
}

In the else branch (with a redundant condition, but your compiler can probably eliminate that), you construct a new wave_function object and then discard it. wave_function(); here will not invoke the default constructor.


Throughout your code, there are uses of std::pow with constant exponents. In general, you can expect x*x to be faster than std::pow(x, 2) and std::sqrt(x) to be faster than std::pow(x, 0.5) - and both are likely to be more accurate into the bargain.


(This is an incomplete answer - Real Life has called me away. I will return with additional review later.)

lang-cpp

AltStyle によって変換されたページ (->オリジナル) /