- 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.)
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.
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.)