I have a Point3d class for which I created a scalar multiplication operator like so:
Point3d operator*(double mul) { return {x*mul, y*mul, z*mul}; }
This does not seem to multiply doubles correctly. In my testing when I multiply a Point3d object by 10^-6 and then check the x coordinate, I get .000002.
But, when multiplying the components by hand I get 2.1584e-06.
The former definitely only has 1 digit of precision because if the operator is too small the Point3d goes to 0.0. Why is this happening?
If you write them both out without an exponent, you see:
.000002
.0000021584
That means they're equal, to the point where the former stops. So it's almost certainly the printing of the value that's giving you your difference. Try it with something like:
#include <cstdio>
:
printf("%.20f\n", myDouble); // I can't be bothered looking up the iomanp stuff :-)
This should show you more than the default number of digits.
Related
I have a function that takes in an optional distance parameter dist, but my algorithm works with squared distances. If the user does not specify any value, I want dist to be as large a number as possible.
Result foo(double dist = std::sqrt(std::numeric_limits<double>::max())) const;
Is the code above safe, or will it blow up because of rounding errors? Would it be better to use something (even) uglier like
Result foo(double dist = std::sqrt(std::numeric_limits<double>::max() - 100)) const;
If you're careful, you can use std::numeric_limits<double>::infinity . It will do the right thing in comparisons and if you square it, it remains infinite.
I am both tired, new to C++ and real bad at dealing with polynomials. That's a bad combo for my assignment. Nevertheless I am trying to solve it. Please note that I might have misunderstood certain parts both mathematically and language-wise. Maybe even terminology.
The first task of my assignment was to create a class for storing polynomials. I figured the important parts were coefficiants and the degree of the polynomial. As such I have a polynomial class that (partly) looks like this:
class Polynomial {
private:
double* Coefficients; //Array of coefficients in order of ascending power
int Degree; //The degree of the polynomial
...
The class should have a method for finding the integral of the polynomial within a lower and upper bound. But I really do not know how to work with it.
Since it's bad practise not to show what I've done, this is what I currently have, and it probably does not make a lot of sense, but please, if you can, point me in the right direction?
Polynomial Polynomial::ComputeIntegral(double lower, double upper) {
//Values needed to create new polynomial
//degree will be one more than the original polynomial
int degree = Degree + 1;
double* coefficients = new double[degree + 1];
coefficients[0] = 0;
for (int i = 0; i < degree +1; i++) {
coefficients[i + 1] = Coefficients[i] / (double)(i + 1);
}
Polynomial integral(degree, coefficients);
return integral;
}
That I can see myself, it is messed up because a) I do not use the bounds, and b) I am pretty sure per the assignment description I should end up with a value rather than a new polynomial.
Google tells me there are algorithms to deal with finding integrals (Trapezoid for example), but I can not wrap my head around matching that with my representation of a polynomial.
A few pointers:
Use std::vectors instead of pointers and new. (If you are new to C++, there are very few circumstances when you actually need to use new.)
ComputeIntegral(double, double) will need to return a double, since it is obviously computing a definite integral. (The function you have at the moment would be something like GetPrimitive(), as it returns the primitive of the polynomial, which is another poly.
The definite integral is the difference of the primitive evaluated at the bounds (First Fundamental theorem of calculus).
There are a number of ways you could represent the polynomial as a data structure, but I would suggest a single std::vector<double> coeffs that represents all of the coefficients up to the degree of the poly, then the degree can be calculated at coeffs.size(). In some cases there may be zeroes in that coeffs though.
In the general case, it is possible to use the boost library to compute integrals: https://www.boost.org/doc/libs/1_77_0/libs/math/doc/html/quadrature.html
There is also the library ALGLIB that I have used to compute integrals. Here is an example to compute integrals with ALGLIB: Integrate a public but non static member function with ALGLIB
With this question as base, it is well known that we should not apply equals comparison operation to decimal variables, due numeric erros (it is not bound to programming language):
bool CompareDoubles1 (double A, double B)
{
return A == B;
}
The abouve code it is not right.
My questions are:
It is right to round to both numbers and then compare?
It is more efficient?
For instance:
bool CompareDoubles1 (double A, double B)
{
double a = round(A,4);
double b = round(B,4)
return a == b;
}
It is correct?
EDIT
I'm considering round is a method that take a double (number) and int (precition):
bool round (float number, int precision);
EDIT
I consider that a better idea of what I mean with this question will be expressed with this compare method:
bool CompareDoubles1 (double A, double B, int precision)
{
//precition could be the error expected when rounding
double a = round(A,precision);
double b = round(B,precision)
return a == b;
}
Usually, if you really have to compare floating values, you'd specify a tolerance:
bool CompareDoubles1 (double A, double B, double tolerance)
{
return std::abs(A - B) < tolerance;
}
Choosing an appropriate tolerance will depend on the nature of the values and the calculations that produce them.
Rounding is not appropriate: two very close values, which you'd want to compare equal, might round in different directions and appear unequal. For example, when rounding to the nearest integer, 0.3 and 0.4 would compare equal, but 0.499999 and 0.500001 wouldn't.
A common comparison for doubles is implemented as
bool CompareDoubles2 (double A, double B)
{
return std::abs(A - B) < 1e-6; // small magic constant here
}
It is clearly not as efficient as the check A == B, because it involves more steps, namely subtraction, calling std::abs and finally comparison with a constant.
The same argument about efficiency holds for you proposed solution:
bool CompareDoubles1 (double A, double B)
{
double a = round(A,4); // the magic constant hides in the 4
double b = round(B,4); // and here again
return a == b;
}
Again, this won't be as efficient as direct comparison, but -- again -- it doesn't even try to do the same.
Whether CompareDoubles2 or CompareDoubles1 is faster depends on your machine and the choice of magic constants. Just measure it. You need to make sure to supply matching magic constants, otherwise you are checking for equality with a different trust region which yields different results.
I think comparing the difference with a fixed tolerance is a bad idea.
Say what happens if you set the tolerance to 1e-6, but the two numbers you compare are
1.11e-9 and 1.19e-9?
These would be considered equal, even if they differ after the second significant digit. This may not what you want.
I think a better way to do the comparison is
equal = ( fabs(A - B) <= tol*max(fabs(A), fabs(B)) )
Note, the <= (and not <), because the above must also work for 0==0. If you set tol=1e-14, two numbers will be considered equal when they are equal up to 14 significant digits.
Sidenote: When you want to test if a number is zero, then the above test might not be ideal and then one indeed should use an absolute threshold.
If the round function used in your example means to round to 4th decimal digit, this is not correct at all. For example, if A and B are 0.000003 and 0.000004 they would be rounded to 0.0 and would therefore be compared to be equal.
A general purpose compairison function must not work with a constant tolarance but with a relative one. But it is all explained in the post you cite in your question.
There is no 'correct' way to compare floating point values (Even a f == 0.0 might be correct). Different comparison may be suitable. Have a look at http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
Similar to other posts, but introducing scale-invariance: If you are doing something like adding two sets of numbers together and then you want to know if the two set sums are equal, you can take the absolute value of the log-ratio (difference of logarithms) and test to see if this is less than your prescribed tolerance. That way, e.g. if you multiply all your numbers by 10 or 100 in summation calculations, it won't affect the result about whether the answers are equal or not. You should have a separate test to determine if two numbers are equal because they are close enough to 0.
I would like to know how would one represent infinity if there is no built-in function for you to do so.
I know that if we are using float or double, we will be able to use infinity() with #include <limits>. But if I need to use int or in the case of NTL, ZZ, how should I represent infinity? Should I write something new? How is it represented in C++?
Edit: I'm posing this question because I would like to implement an addition algorithm for point on an elliptic curve. So, I'll need infinity to represent the point of infinity. I was wondering if I'll be better off using projective coordinates and have [0:1:0] to represent the point at infinity, but wanted to explore the infinity in int or ZZ option first.
In general, if you are running into infinity on a finite precision machine then you are not addressing the problem at hand correctly with your computational approach. You should either analytically deal with the infinity before hand or find a means to appropriately avoid it in finite precision. For instance, if you had to deal with f(x)=sin(x)/x you probably wouldn't want to let your code evaluate this in finite precision at x = 0. Instead you would want to check if x is 0 and then return f(0) = 1.0.
What about just a symbolic representation such that it "acts", in a general sense, as infinity would?
You can certainly do something like that. For most computational problems that wont get you anywhere useful. A simple way to approach that would be to create your own data types and override all of the operators to handle infinity appropriately. Not all infinities are the same though so you would need to deal with that issue. For example, you might define a customized float to be something like
class MyFloat
{
public:
MyFloat(float a):
m_val(a),
m_isInf(false),
m_orderInf(0)
{}
bool isInf(){return m_isInf;}
int orderInf(){return m_orderInf;}
float value(){return m_val;}
// define custom operators
MyFloat & operator+= (MyFloat const & rhs)
{
if(rhs.isInf() || m_isInf)
{
m_orderInf = m_orderInf > rhs.orderInf() ? m_orderInf : rhs.orderInf();
m_isInf = true;
}
else
{
m_val += rhs.value();
}
return *this;
}
// other operators you would need to define
MyFloat & operator/= (MyFloat const & rhs);
MyFloat & operator*= (MyFloat const & rhs);
private:
float m_val;
bool m_isInf;
int m_orderInf;
};
NOTE: You will need to give a lot of thought as to how to treat both zeros and infinities. The above code is not well thought out, but I hope it gives you something to think about.
i am trying to get the 'cross product' of two vectors. these two vectors represent two planes. so, my vectors are as a1,b1,-1 and a2,b2,-1. (I used, my plane equation as ax+by-z+d=0).
this was my defined function to get the cross product;
vector<double> cross_vector(vector<double> plane1,vector<double> plane2){
vector<double> cross_product;
double a1=plane1.at(0); double a2=plane2.at(0);
double b1=plane1.at(1); double b2=plane2.at(1);
int c1,c2=-1;
double cross_a=(b1*c2)-(b2*c1);
double cross_b=(a2*c1)-(a1*c2);
double cross_c=(a1*b2)-(a2*b1);
cross_product.push_back(cross_a);
cross_product.push_back(cross_;
cross_product.push_back(cross_c);
return cross_product;
}
for the result i got as below result for different plane combinations;
523554 -1.3713e+006 -0.00160687
556340 -1.43908e+006 0.00027957
-568368 1.46225e+006 -0.00034963
143455 -380017 -0.00027957
i can't understand the values like 1.46225e+006? is there any wrong with my function?
i know, my resultant cross vector should be directed exactly horizontal. So, could you also tell me how can i check whether my cross-vector is horizontal or not?
hope your advices.
int c1,c2=-1;
This leaves c1 uninitialized. Use:
int c1=-1, c2=-1;
The math looks correct. Placing a quick A = <1,0,0> and B = <0, 1, 0> gave a reasonable result on the backside of <0, 0, 1>. The e notatin represent the number times 10 to the power after the e. So those might be reasonable as well, but it's hard to say as from your example I can't tell what your input values were. I wouldn't personnaly return the value directly though - I'd prefer to return as a reference or pointer to prevent needless copying. Also, as the above poster mentioned, you do have an initialized var.