For some home work I'm doing the following:
int main() {
ofstream file("log.txt");
file << setw(5) << "i"
<< setw(15) << "h"
<< setw(15) << "n"
<< setw(15) << "sum"
<< setw(15) << "diff"
<< endl;
auto write2file = [&file](int i, double h, double n, double sum, double diff) {
file << setw(5) << i
<< setw(15) << h
<< setw(15) << n
<< setw(15) << sum
<< setw(15) << diff
<< endl;
};
double a = 0;
double b = 2;
int n = 1;
double h = (b-a)/n;
double sum = sum_analytic;
double diff = 1;
while (diff > pow(10, -4)) {
h = (b-a)/++n;
sum = ntgrt(a, b, n, h);
diff = abs(sum - sum_analytic);
static int i = 0;
write2file(++i, h, n, sum, diff);
}
}
Considering the C++17 if init
feature (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html) I'm kind of seing the same pattern here when I declare h
, sum
and diff
outside the while
loop but they are used only inside.
Is there a better way to write it, may be taking advantage of C++17 features?
Then what you want is a for
loop:
for(double diff = 1; diff > pow(10, -4);)
{
double h = (b-a)/++n;
double sum = ntgrt(a, b, n, h);
diff = abs(sum - sum_analytic);
....
}
There was no point in adding this capability to while
since you can just use for
and leave off the increment statement.
I'd start with some C++98 features to reduce repetition.
template <class I, class F>
void write2file(std::ostream &os, I i, F h, I n, F sum, F diff) {
using std::setw;
os << setw(5) << i
<< setw(15) << h
<< setw(15) << n
<< setw(15) << sum
<< setw(15) << diff
<< "\n";
}
// ...
write2file(file, "i", "h", "n", "sum", "diff");
// ...
write2file(file, ++i, h, n, sum, diff);
It would appear that when they're used, i
and n
always have the same value. I'd just use one of the two rather than both.
Your pow(10, -4)
would probably be better off as 1e-4
.
I think some good use of C++98 can probably clean up the loop as well. I'd move it into a function template, something on this general order:
template <typename F>
void show_convergence(double a, double b, F f, double sum_a, std::ostream &os) {
double diff = 1.0;
for (int n=1; diff > 1e-4; n++) {
double h = (b-a)/n;
double sum = f(a, b, n, h);
diff = abs(sum-sum_a);
write2file(os, n, h, sum, diff);
}
}
Technically, this wouldn't have to be a template--but it's fairly harmless, and avoids the ugliness of a pointer to a function (which can also lead to a fair degree of inefficiency). Then you'd call this something like this:
show_convergence(0, 2, ntgrt, sum_analytic, file);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With