'The sum of a sequence
I'm trying to make a function for calculating this formula
#include <iostream>
#include <vector>
double Sequence(std::vector < double > & a) {
double result = 0;
for (int i = a.size() - 1; i > 0; i--) {
if (a[i] == 0) throw std::domain_error("Dividing with 0");
if (i > 1)
result += 1 / (a[i - 1] + 1 / a[i]);
else result += a[i - i];
std::cout << a[i] << " " << result << " " << "\n";
}
return result;
}
int main() {
std::vector<double>a{1,2,3,4,5};
try {
std::cout << Sequence(a);
} catch (std::domain_error e) {
std::cout << e.what();
}
return 0;
}
Code gives correct result for {1,2,3} sequence. However, if I add a few numbers to that sequence result becomes wrong. Could you help me to fix this?
Solution 1:[1]
if (i > 1)
result += 1 / (a[i - 1] + 1 / a[i]);
else result += a[i - i];
This is wrong; it just happens to work if you have three or fewer terms.
The recurrence you actually want is
if (i == a.size() - 1) {
result = a[i];
} else {
result = a[i] + 1 / result;
}
you can see that this is a correct recurrence by the fact that Tidying up some more things (removing the condition from inside the loop, fixing an off-by-one in the loop termination condition, and correcting the exception condition):
double Sequence(std::vector<double> &a) {
double result = a[a.size() - 1];
for (int i = a.size() - 1; i >= 0; i--) {
if (result == 0)
throw std::domain_error("Dividing with 0");
result = a[i] + 1 / result;
}
return result;
}
Solution 2:[2]
This known as the Simple Continued Fraction where all numerators are 1s. It is basically represented as [a1;a2,a3,...,an]
(well in fact starts from a0
but whatever). You can calculate the result from top to bottom while obtaining a better approximation (or convergent as they call it) at each step.
The result of this finite rational series or infinite irrational series is expressed as p/q
. In order to calculate the result you assume
p0 1 p1 a1 p2 a2*p1+p0 p3 a3*p2+p1 pn a_n*p_n-1+p_n-2
__ = _ and __ = __ then __ = ________ then __ = ________ .. then .. __ = _______________
q0 0 q1 1 q2 a2*q1+q0 q3 a3*q2+q1 qn a_n*q_n-1+q_n-2
and every next p_x/q_x
yields a better appoximation to the result.
Say if you are given a decimal like 1.425
in continued fraction cefficients as
[1; 2, 2, 1, 5]
a.k.a.
1
1 + _____________
1
2 + _________
1
2 + _____
1
1 + _
5
Then the intermediate convergents calculated as described above would be;
1 1 3 7 10 57
_ -> _ -> _ -> _ -> __ -> __ = 1.425
0 1 2 5 7 40
Notice that each convergent overshoots up and down from the final result subsequently besides 57/40
being the minimal rational expression of 1.425
.
Continued fractions are a very deep topic which in fact eliminates the floating point error once an arithmetic is establised among them in their continued fractions form.
You can play here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |