The following code is designed to implement this formula:
void integrate ( double R , double E ) //radius and acceptable error, entered by user
{
int i = 1; //iterator
int n = 1; //number of rectangles
double x = 0;
double width = 0; //stores width of each rectangle
double area = 0; //stores calculated area
double error = E + 1; //stores difference between calculated area and pi*(radius)^2
while ( error > E ) //loop continues as long as error is greater than the acceptable limit entered by user
{
width = R / n; //sets the width of rectangles
area = 0; //with this line, calculated area converges to zero. without it, calculated area increases without bound
while ( i <= n )
{
x = i; //assign iterator value to a separate variable to avoid data type issues in calculation
area += width * sqrt ( pow ( R , 2.0 ) - pow ( width * ( x - 0.5 ) , 2.0 ) ); //riemann integral formula
i++;
}
n++; //increase number of rectangles by 1 to be used in next loop
area *= 4; //forumla uses one quarter of a circle, multiply by 4 to get total area
error = abs ( area - ( pi * pow ( R , 2.0 ) ) ); //error calculation
cout << " \n Calculated area = " << area << "\n" //debugging output
<< " \n Error = " << error << "\n";
cin.get();
}
cout << "\n Area: " << area << "\n" //output to user
<< "\n Error: " << error << "\n"
<< "\n Iterations: " << i << "\n";
return;
}
As the comment says, when the line "area = 0;" is included in the first loop, the area converges to zero, and when it is removed, the area increases without bound. I've been working on this one function for the better part of a week without progress. The rest of the program is completed, tested, and works fine. I have to assume that there's either an error in the logic or the math that I just can't see. Any help would be appreciated.
I hope that the comments are sufficient. I'll provided additional clarification as necessary.
(This is a self-contained function. No other part of the program affects it or is affected by it aside from the user input.)
Related
I've an array of 2500 steps taken by a robot, each step taken in a random direction (up, down, right, or left). I'm supposed to store the Euclidian distance (a right triangle's hypotenuse) of each step from the robot's origin. No problem there.
I'm also supposed to keep tabs on the max. Euclidian distance the robot reaches, so if the current distance is greater than one of the previous ones, the current one becomes the new greatest distance. Here's my code:
int main(){
int steps[2500];
int randDir[2500];
int coords[2] = {0,0};
int path[2500][2];
double eucliDist[2500];
eucliDist[0] = 1;
double maxEucliDist;
double taxiDist;
for (int i = 0; i < 2500; i++){
randDir[i] = rand() % 4;
steps[i] = i + 1;
switch(randDir[i]){
case 0:
coords[0] = coords[0] + 1;
break;
case 1:
coords[1] = coords[1] + 1;
break;
case 2:
coords[0] = coords[0] - 1;
break;
case 3:
coords[1] = coords[1] - 1;
break;
}
eucliDist[i] = sqrt((pow(coords[0],2)) + (pow(coords[1],2)));
if (eucliDist[i] > eucliDist[i-1]){
maxEucliDist = eucliDist[i]; //need to fix this. Not showing true max Euclid. Dist.
taxiDist = abs(coords[0]) + abs(coords[1]);
}
//cout << "Step " << steps[i] << " Euclidian distance from origin is: " << eucliDist[i] <<endl; //check euclidian dist each step
//cout << steps[i] << "\t Coords (" << coords[0] << ", " << coords[1] << ")" << "\n"; //check coords with each step
}
cout << "Final Coordinates: (" << coords[0] << ", " << coords[1] << ")" << endl;
cout << "Maximum Euclidian distance was: " << maxEucliDist << endl;
cout << "'Taxicab' distance is: " << taxiDist << endl;
cin.get();}
Problem is that my output shows the wrong max, as shown in the snippet of my output below:
Program output showing incorrect maximum Euclidian distance
FYI, "taxicab" distance is the distance a 2nd robot would have to take to get to the 1st robot's position at max distance if it needed to (it's a right triangle's base + height since traveling on a grid).
Not sure what I'm doing wrong. Might have something to do with my if-statement in the bottom half of the code.
Any thoughts?
Your problem is indeed your if-statement:
if (eucliDist[i] > eucliDist[i-1]){ // THIS IS WRONG
maxEucliDist = eucliDist[i]; // THIS IS ACTUALLY OK
taxiDist = abs(coords[0]) + abs(coords[1]);
}
You're comparing your current distance to the distance in the PREVIOUS frame, not your maximum. You also need to initialize your maximum to zero, since it needs something to start with too, or else your comparison will be "current" versus "garbage". C++ does not initialize local variables to zero.
Your new if-statement should be this:
if (eucliDist[i] > maxEucliDist){
maxEucliDist = eucliDist[i];
taxiDist = abs(coords[0]) + abs(coords[1]);
}
Your first job is to recognise that the square of a positive number is a monotonic function of the number. So stop taking those square roots all over the place (which are difficult for a computer to evaluate), and work in distance squared, until you come to display the final result.
Then you can replace the nasty pow(x, 2) functions with x * x and work in integer arithmetic. (Take steps to avoid overflowing an int though.). This will be at least an order of magnitude faster.
Your specific issue is a logic error in that you are only comparing your new distance with the previous one, not the minimum found thus far.
I'm reviewing some numerical methods for integration. I came across Rectangular integration method (i.e. Euler's method). According to the book I'm reading, the actual algorithm is
The code is self-explanatory. The author provides this example dxdt=cos(t) with an initial value x(0)=0. The analytical solution is x=sin(t). We can compute the error at t=1 and indeed the author provides it in the following table:
The problem is that in my following code, the error is 9.1% but in the preceding table, the error actually is 2.6. Did I make a mistake?
#include <iostream>
#include <cmath>
int main()
{
double x(0.0), dxdt, t(0.0), T(0.1), stopTime(1.0);
for ( ; t <= stopTime; t += T ){
dxdt = cos(t);
x += dxdt*T;
if ( t > 0.9 )
std::cout << "Time: " << t << " Error: " << fabs( (x - sin(t)) /sin(t) )*100.0 << std::endl;
}
return 0;
}
You need to take into account that while x is updated to an approximation of x(t+T), the loop variable t will only be incremented at the very end of the loop, so retains it value t during the output. This time mismatch introduces an additional relative error of abs(sin(t+T)/sin(t)-1) which for t=1, T=0.1 is about 5.91 %.
You should also make the loop stable under rounding errors in the t incrementation, either by computing the exact number of loops or by choosing bounds in the inequality that are in-between the steps as in
while ( t < stopTime-0.5*T ){
dxdt = cos(t);
x += dxdt*T;
t += T;
if ( t > stopTime -2.5*T )
std::cout << "Time: " << t << " Error: " << fabs( (x - sin(t)) /sin(t) )*100.0 << std::endl;
}
I'm estimating the value of Pi using the following formula:
Using the following C++ code:
double sub = 0;
int prec = 1000; //How many iterations to use in estimate.
for(int i = 1; i <= prec; i++){
double frac = 1/((3+(2*(i-1))) * pow(3, i));
sub += (i == 1) ? 1-frac : (i%2) ? -frac : frac;
}
double pi = sqrt(12)*sub;
cout << "Pi estimated with precision of " << prec << " iterations is " << pi << ".\n";
My problem is that even at 1000 (or 100000 for that matter) iterations, the highest precision I'm getting is 3.14159. I've tried using static_cast<double>() on each of the numbers in the calculation but still get the same result. Am I doing something wrong here, or is this the max precision this method will yield? I'm new to C++, but not to programming.
the problem is you don't print all the precisions. you need to call,
std::cout << std::setprecision(10) << ...
I'm running the following code:
double Scos [61][61][61] = {0};
double kdotr;
int ik;
int howmany [34] = {0};
auto Fs_ = initializer_list<int>({0});
copy(Fs_.begin(), Fs_.end(), Fs);
for ( size_t z=0; z<5; ++z )
{
for ( size_t y=0; y<5; ++y )
{
for ( size_t x=0; x<10; ++x )
{
for ( int k1=0; k1<=60; ++k1 )
{
for ( int k2=0; k2<=60; ++k2 )
{
for ( int k3=0; k3<=60; ++k3 )
{
int i = x+y*10+z*50;
kdotr = (double)dQ*( (k1-30)*(x_[i][0]-x) + (k2-30)*(x_[i][1]-y) + (k3-30)*(x_[i][2]-z) );
if ( isnan(kdotr) )
cout << "kdotr " << k1 << " " << k2 << " " << k3 << endl;
Scos[k1][k2][k3] += (double)cos(kdotr);
if ( isnan(Scos[k1][k2][k3]) )
cout << "Scos " << k1 << " " << k2 << " " << k3 << endl;
}
}
}
}
}
}
for ( int k1=0; k1<=60; ++k1 )
{
for ( int k2=0; k2<=60; ++k2 )
{
for ( int k3=0; k3<=60; ++k3 )
{
double k = (double)dQ*sqrt( pow((k1-30),2) + pow((k2-30),2) + pow((k3-30),2) );
ik = round(k/0.1);
Fs[ik] += Scos[k1][k2][k3];
if ( isnan(Fs[ik]) )
cout << "Fs[ik] " << k1 << " " << k2 << " " << k3 << endl;
++howmany[ik];
}
}
}
At the beginning there are just some declarations and initializations (array Fs was already declared somewhere else, together with dQ and x_).
I put calls to isnan because the code strangely returns some NaNs. At first, I believed the problem was with kdotr going to infinity, which would have been argument of cos; however, the code never fails at Scos, but at some Fs[ik]. This does not make sense to me, since Fs comes from a simple sum (and it is initialized to 0).
Has ever happened to you to obtain NaN after a sum between finite terms in C++?
This sort of problem is ALWAYS caused by some input to a calculation either being "invalid" (leading to the FPU generating a NaN as the result) or using "NaN" as an input in itself.
In this case, having a quick scan through the operations you do, it seems like there are only operations that don't generate NaN based on (for example) negative inputs [like sqrt or log would do], so my thinking is that one or more of your inputs are reading uninitialized (or incorrectly initialized) data.
I would start by checking that all the components of:
x_[i][0]-x) + (k2-30)*(x_[i][1]-y) + (k3-30)*(x_[i][2]-z
are not NaN. In particular x_[i][0,1,2].
Since your code is not a complete piece of exectutable code, and some variable's initialization isn't even in the code-snippet, it will be impossible for anyone here to give you a precise answer to where in your code it is going wrong.
Ok, I make the code work without NaNs.
As some commenters pointed out, there could be problems with the initializations. In fact, instead of using directly Fs (which is a member of a greater class - this code itself is part of a method), I stored the sums of cosines in a temporary array Fs_, declared and initialized inside the method (e.g. like Scos): now there are no NaNs anymore.
Im trying to get the time elapse percentage, what I do is first check a time interval, them I want to get the percentage of the elapsed time in that time interval, if that makes sense
Here is my code:
if ( ofGetElapsedTimeMillis() > lastTimeCheck + timePeriod ) {
lastTimeCheck = ofGetElapsedTimeMillis();
cout << "its time!" << endl;
}
float p = (float)ofGetElapsedTimeMillis() / (float)(lastTimeCheck + timePeriod);
cout << "time percentage: " << p << endl;
timePeriod = 3000, so every 3 seconds I update the lastTimeCheck variable and the following line of code gets the percentage in that time interval, I get results from 0.5 to 0.9, but I need p to be from 0 to 1
Thanks in advance
- rS
Do you mean the time between lastTimeCheck and lastTimeCheck + timePeriod? That would be
float p = (float)(ofGetElapsedTimeMililis() - lastTimeCheck) / (float)(timePeriod);
You can probably lose one of the float casts too, but I think it's safer and no less readable to leave them in. If you need to guarantee that p is less than or equal to one, though, you should either save and re-use the ofGetTimeElapsedMillis value from the previous call or you should explicitly check p afterwards.
int millisNow = ofGetElapsedTimeMillis();
int millisSinceLastCheck = millisNow - lastTimeCheck;
if (millisSinceLastCheck > timePeriod) {
lastTimeCheck = millisNow;
millisSinceLastCheck = 0;
cout << "it's time!" << endl;
}
float p = (float)(millisSinceLastcheck) / (float)(timePeriod);
cout << "time fraction: " << p << endl;