Why am I getting zero for all values in this expression? - c++

Following is a fragment of a program for deducing whether or out 2 lines intersect.
P and P2 are CPoint objects marking the start and end point of one of the 2 lines.
double m1,m2; //slopes
double b1,b2; //y-intercepts
double y,x; //intersection point
m1=(max(P.y,P2.y) - min(P.y,P2.y)) /( max(P.x,P2.x) - min(P.x,P2.x) );
For some reason I'm always getting m1 to be 0. Why's that?

If your CPoint class is a point with integer coordinates, you have to do some conversion here to get the result you want. See the following demonstration of the problem. Consider two points P = (1, 4) and P2 = (5, 3):
m1=( max(P.y,P2.y) - min(P.y,P2.y) ) / ( max(P.x,P2.x) - min(P.x,P2.x) );
^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
4 3 5 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1 4
However, in integer division, 1 / 4 is 0, but you want the result to be 0.25. The fact that the result variable has a type of double doesn't change the value (and type) of the expression.
To solve this problem, you have to cast the parts of your expression just before it becomes relevant that they are to be considered as non-integral numbers. In your case this are the operands of the division, so that it will be a floating point division. (Casting the result of the division will also not help.)
m1 = static_cast<double>( max(P.y,P2.y) - min(P.y,P2.y) )
/ static_cast<double>( max(P.x,P2.x) - min(P.x,P2.x) );
Note that casting the second operand is optional, as double / int always uses floating point division.
Also note that your expression calculates the absolute value of the slope. You might want to calculate the signed slope.
Something you can improve in your code (this won't solve the problem above): Instead of subtracting the min of the max of the difference, just take the absolute value of the difference:
m1 = static_cast<double>( abs(P.y - P2.y) )
/ static_cast<double>( abs(P.x - P2.x) );
Since in C++, abs is a template function (in C it's a macro, urgh...), you can also force a result type using explicit template types:
m1 = abs<double>(P.y - P2.y)
/ abs<double>(P.x - P2.x);
Also, as the calculation of a slope between two given points seems to be a commonly used function, you can implement this as a free-standing function on two CPoints:
double absoluteSlope(const CPoint & p, const CPoint & q) {
return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}
Even better, to make use of C++ templates, implement it on a generic class which has the members x and y:
template<class T>
double absoluteSlope(const T & p, const T & q) {
return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}
This solution now works for your CPoint instance with integer coordinates as well as a (maybe upcoming) CPointF class with float / double coordinates.
As already warned above, this calculates the absolute slope. To change this to a mathematically correct (signed) slope, just replace abs with static_cast:
template<class T>
double slope(const T & p, const T & q) {
return static_cast<double>(p.y - q.y) / static_cast<double>(p.x - q.x);
}

The division A/B should A/(double)B. Use this in your code.
Fabs instead of abs too.

Related

How to increase accuracy of floating point second derivative calculation?

I've written a simple program to calculate the first and second derivative of a function, using function pointers. My program computes the correct answers (more or less), but for some functions, the accuracy is less than I would like.
This is the function I am differentiating:
float f1(float x) {
return (x * x);
}
These are the derivative functions, using the central finite difference method:
// Function for calculating the first derivative.
float first_dx(float (*fx)(float), float x) {
float h = 0.001;
float dfdx;
dfdx = (fx(x + h) - fx(x - h)) / (2 * h);
return dfdx;
}
// Function for calculating the second derivative.
float second_dx(float (*fx)(float), float x) {
float h = 0.001;
float d2fdx2;
d2fdx2 = (fx(x - h) - 2 * fx(x) + fx(x + h)) / (h * h);
return d2fdx2;
}
Main function:
int main() {
pc.baud(9600);
float x = 2.0;
pc.printf("**** Function Pointers ****\r\n");
pc.printf("Value of f(%f): %f\r\n", x, f1(x));
pc.printf("First derivative: %f\r\n", first_dx(f1, x));
pc.printf("Second derivative: %f\r\n\r\n", second_dx(f1, x));
}
This is the output from the program:
**** Function Pointers ****
Value of f(2.000000): 4.000000
First derivative: 3.999948
Second derivative: 1.430511
I'm happy with the accuracy of the first derivative, but I believe the second derivative is too far off (it should be equal to ~2.0).
I have a basic understanding of how floating point numbers are represented and why they are sometimes inaccurate, but how can I make this second derivative result more accurate? Could I be using something better than the central finite difference method, or is there a way I can get better results with the current method?
The accuracy can be increased by choosing a type which has more precision. float is currently defined as an IEEE-754 32-bit number, giving you a precision of ~7.225 decimal places.
What you want is the 64-bit counterpart: double with ~15.955 decimal places accuracy.
That should be sufficient for your calculation, however worth mentioning is boosts implementation which offers a quadruple-precision floating point number (128-bit).
Finally The GNU Multiple Precision Arithmetic Library offers types with an arbitrary number of decimal places for precision.
Go analytical. ;-) probably not an option given "with the current
method".
Use double instead of float.
Vary the epsilon (h), and combine the results in some way. For example you could try 0.00001, 0.000001, 0.0000001 and average them. In fact, you'd want the result with the smallest h that doesn't overflow/underflow. But it's not clear how to detect overflow and underflow.

Anyway to avoid floating point operation for Max Points on Line problem

I'm trying to solve "Max Points on Line" problem on Leet code. I inevitably need to do floating point operation to calculation Y-Intercept and slope of each line. Due to my past bad experience, I'm trying to avoid floating point operations as much as I can. Do you have any suggestion how I can do that here?
I am using LeetCode framework for development and pretty much just have access to standard C++ library.
Tried using double or long double but one of the test cases already pushes the numbers to the limits of the accuracy of these data types.
//P1[0] is X coordinate for point P1 and P1[1] is Y coordinate
long double slopeCalc( vector<int> &p1, vector<int> &p2 )
{
if( p1[0] == p2[0] && p1[1] == p2[1] )
{
return DBL_MIN;
}
if( p1[0] == p2[0] && p1[1] != p2[1] )
{
return DBL_MAX;
}
return ( (long double)p2[1] - (long double)p1[1] ) / ((long double)p2[0] - (long double)p1[0]);
}
long double yIntersectionCalc( vector<int> &p1, vector<int> &p2 )
{
if( p1[0] == p2[0] && p1[1] == p2[1] )
{
return DBL_MIN;
}
if( p1[0] == p2[0] && p1[1] != p2[1] )
{
return DBL_MAX;
}
return ((long double)p1[1]*(long double)p2[0] - (long double)p2[1]*(long double)p1[0]) / (long double)(p2[0] - p1[0]);
}
If the two points are (0, 0) and (94911150, 94911151) the slope is calculated as 1 which is inaccurate. I'm trying to avoid the floating point division if possible.
NOTE: Max Points on a Line problem is to be given points in 2D space (in this case integer coordinates) and find the maximum number of points that are on one line. E.g if the points are (0,0), (2,2), (4,3), (1,1) the answer is 3 which are points (0,0), (1,1), and (2,2)
In integer coordinates, the alignment test of three points can be written as the expression
(Xb - Xa) (Yc - Ya) - (Yb - Ya) (Xc - Xa) = 0
Assuming that the range of the coordinates requires N bits, the computation of the deltas takes N+1 bits, and exact evaluation of the expression takes 2N+2 bits at worse. There is little that you can do against that.
In your case, 64 bits integers should be enough.
A piece of advice: avoid working with the slope/intercept representation.
If you want to avoid using floating point, what you can do to determine if a point z is collinear with two other points x and y is to compute the determinant of the matrix
{{1,z1,z2},{1,x1,x2},{1,y1,y2}}
If the determinant is 0, then they are collinear. Since computing the determinant using the permutation definition involves only multiplication and addition/subtraction, all your computations will remain as integers. The reason it will be 0 is that the determinant is twice the area of the triangle with x,y,z as vertices,which is zero if and only if the triangle is degenerate.
Another approach would be to use Fraction objects, in particular the slope and the intercept of the lines defined by two integers are identified as Fractions ("rational numbers"), and a reduced fraction is identified by its numerator and denominator, so you can use the pair of fractions (slope,intercept) as identifiers and since you never use floating point arithmetic you won't need to deal with roundoff error. See https://martin-thoma.com/fractions-in-cpp/ for a sample implementation of Fractions, the important part is that you can use the arithmetic operators, and normalization.
EDIT: boost has a rational number library, if you want to use it https://www.boost.org/doc/libs/1_68_0/libs/rational/
Given points a,b,c, look at the slopes b,c make to a common point, a:
ba.x = b.x - a.x
ba.y = b.y - a.y
ba.s = ba.y / ba.x
ca.x = c.x - a.x
ca.y = c.y - a.y
ca.s = ca.y / ca.x
The points a,b,c are co-linear iff the lines AB and BC have a common slope, i.e.:
ba.s == ca.s
Substituting and rearranging to remove the divides:
ba.y / ba.x == ca.y / ca.x
ba.y * ca.x / ba.x == ca.y
ba.y * ca.x == ca.y * ba.x
Substitute in the original formulas for those, then a,b,c are co-linear iff:
(b.y - a.y) * (c.x - a.x) == (c.y - a.y) * (b.x - a.x)
Note that the determinant answer could also be rearranged into this form which proves this approach. But this form has just 2 multiplications rather than 12 for a naive determinant implementation.

C++ math expression from math formula

I try to convert this math formula in C++ expression
But I'm doing something wrong
(log(1.0+a*(getpixel(j,k)))/log10( y ))/(log(2.0)/log10( y ))
First, the log function already computes the logarithm to the base e. You don't need to perform any change-of-base.
Second, split your expression into parts to make it easier to write, and to understand:
const double F = getpixel(j, k);
const double numerator = log(1.0 + a * F);
const double denominator = log(2.0);
const double result = numerator / denominator;
You could choose to split it more (e.g. store the a*F, and 1 + a*F separately too).
Once you've got that, if you really want it in a single line, it's easy enough to combine (but there's no need; the compiler will typically merge constant expressions together for you):
const double result = log(1.0 + a * getpixel(j, k) / log(2.0);

finding cube root in C++?

Strange things happen when i try to find the cube root of a number.
The following code returns me undefined. In cmd : -1.#IND
cout<<pow(( double )(20.0*(-3.2) + 30.0),( double )1/3)
While this one works perfectly fine. In cmd : 4.93242414866094
cout<<pow(( double )(20.0*4.5 + 30.0),( double )1/3)
From mathematical way it must work since we can have the cube root from a negative number.
Pow is from Visual C++ 2010 math.h library. Any ideas?
pow(x, y) from <cmath> does NOT work if x is negative and y is non-integral.
This is a limitation of std::pow, as documented in the C standard and on cppreference:
Error handling
Errors are reported as specified in math_errhandling
If base is finite and negative and exp is finite and non-integer, a domain error occurs and a range error may occur.
If base is zero and exp is zero, a domain error may occur.
If base is zero and exp is negative, a domain error or a pole error may occur.
There are a couple ways around this limitation:
Cube-rooting is the same as taking something to the 1/3 power, so you could do std::pow(x, 1/3.).
In C++11, you can use std::cbrt. C++11 introduced both square-root and cube-root functions, but no generic n-th root function that overcomes the limitations of std::pow.
The power 1/3 is a special case. In general, non-integral powers of negative numbers are complex. It wouldn't be practical for pow to check for special cases like integer roots, and besides, 1/3 as a double is not exactly 1/3!
I don't know about the visual C++ pow, but my man page says under errors:
EDOM The argument x is negative and y is not an integral value. This would result in a complex number.
You'll have to use a more specialized cube root function if you want cube roots of negative numbers - or cut corners and take absolute value, then take cube root, then multiply the sign back on.
Note that depending on context, a negative number x to the 1/3 power is not necessarily the negative cube root you're expecting. It could just as easily be the first complex root, x^(1/3) * e^(pi*i/3). This is the convention mathematica uses; it's also reasonable to just say it's undefined.
While (-1)^3 = -1, you can't simply take a rational power of a negative number and expect a real response. This is because there are other solutions to this rational exponent that are imaginary in nature.
http://www.wolframalpha.com/input/?i=x^(1/3),+x+from+-5+to+0
Similarily, plot x^x. For x = -1/3, this should have a solution. However, this function is deemed undefined in R for x < 0.
Therefore, don't expect math.h to do magic that would make it inefficient, just change the signs yourself.
Guess you gotta take the negative out and put it in afterwards. You can have a wrapper do this for you if you really want to.
function yourPow(double x, double y)
{
if (x < 0)
return -1.0 * pow(-1.0*x, y);
else
return pow(x, y);
}
Don't cast to double by using (double), use a double numeric constant instead:
double thingToCubeRoot = -20.*3.2+30;
cout<< thingToCubeRoot/fabs(thingToCubeRoot) * pow( fabs(thingToCubeRoot), 1./3. );
Should do the trick!
Also: don't include <math.h> in C++ projects, but use <cmath> instead.
Alternatively, use pow from the <complex> header for the reasons stated by buddhabrot
pow( x, y ) is the same as (i.e. equivalent to) exp( y * log( x ) )
if log(x) is invalid then pow(x,y) is also.
Similarly you cannot perform 0 to the power of anything, although mathematically it should be 0.
C++11 has the cbrt function (see for example http://en.cppreference.com/w/cpp/numeric/math/cbrt) so you can write something like
#include <iostream>
#include <cmath>
int main(int argc, char* argv[])
{
const double arg = 20.0*(-3.2) + 30.0;
std::cout << cbrt(arg) << "\n";
std::cout << cbrt(-arg) << "\n";
return 0;
}
I do not have access to the C++ standard so I do not know how the negative argument is handled... a test on ideone http://ideone.com/bFlXYs seems to confirm that C++ (gcc-4.8.1) extends the cube root with this rule cbrt(x)=-cbrt(-x) when x<0; for this extension you can see http://mathworld.wolfram.com/CubeRoot.html
I was looking for cubit root and found this thread and it occurs to me that the following code might work:
#include <cmath>
using namespace std;
function double nth-root(double x, double n){
if (!(n%2) || x<0){
throw FAILEXCEPTION(); // even root from negative is fail
}
bool sign = (x >= 0);
x = exp(log(abs(x))/n);
return sign ? x : -x;
}
I think you should not confuse exponentiation with the nth-root of a number. See the good old Wikipedia
because the 1/3 will always return 0 as it will be considered as integer...
try with 1.0/3.0...
it is what i think but try and implement...
and do not forget to declare variables containing 1.0 and 3.0 as double...
Here's a little function I knocked up.
#define uniform() (rand()/(1.0 + RAND_MAX))
double CBRT(double Z)
{
double guess = Z;
double x, dx;
int loopbreaker;
retry:
x = guess * guess * guess;
loopbreaker = 0;
while (fabs(x - Z) > FLT_EPSILON)
{
dx = 3 * guess*guess;
loopbreaker++;
if (fabs(dx) < DBL_EPSILON || loopbreaker > 53)
{
guess += uniform() * 2 - 1.0;
goto retry;
}
guess -= (x - Z) / dx;
x = guess*guess*guess;
}
return guess;
}
It uses Newton-Raphson to find a cube root.
Sometime Newton -Raphson gets stuck, if the root is very close to 0 then the derivative can
get large and it can oscillate. So I've clamped and forced it to restart if that happens.
If you need more accuracy you can change the FLT_EPSILONs.
If you ever have no math library you can use this way to compute the cubic root:
cubic root
double curt(double x) {
if (x == 0) {
// would otherwise return something like 4.257959840008151e-109
return 0;
}
double b = 1; // use any value except 0
double last_b_1 = 0;
double last_b_2 = 0;
while (last_b_1 != b && last_b_2 != b) {
last_b_1 = b;
// use (2 * b + x / b / b) / 3 for small numbers, as suggested by willywonka_dailyblah
b = (b + x / b / b) / 2;
last_b_2 = b;
// use (2 * b + x / b / b) / 3 for small numbers, as suggested by willywonka_dailyblah
b = (b + x / b / b) / 2;
}
return b;
}
It is derives from the sqrt algorithm below. The idea is that b and x / b / b bigger and smaller from the cubic root of x. So, the average of both lies closer to the cubic root of x.
Square Root And Cubic Root (in Python)
def sqrt_2(a):
if a == 0:
return 0
b = 1
last_b = 0
while last_b != b:
last_b = b
b = (b + a / b) / 2
return b
def curt_2(a):
if a == 0:
return 0
b = a
last_b_1 = 0;
last_b_2 = 0;
while (last_b_1 != b and last_b_2 != b):
last_b_1 = b;
b = (b + a / b / b) / 2;
last_b_2 = b;
b = (b + a / b / b) / 2;
return b
In contrast to the square root, last_b_1 and last_b_2 are required in the cubic root because b flickers. You can modify these algorithms to compute the fourth root, fifth root and so on.
Thanks to my math teacher Herr Brenner in 11th grade who told me this algorithm for sqrt.
Performance
I tested it on an Arduino with 16mhz clock frequency:
0.3525ms for yourPow
0.3853ms for nth-root
2.3426ms for curt

Is there a C/C++ function to safely handle division by zero?

We have a situation we want to do a sort of weighted average of two values w1 & w2, based on how far two other values v1 & v2 are away from zero... for example:
If v1 is zero, it doesn't get weighted at all so we return w2
If v2 is zero, it doesn't get weighted at all so we return w1
If both values are equally far from zero, we do a mean average and return (w1 + w2 )/2
I've inherited code like:
float calcWeightedAverage(v1,v2,w1,w2)
{
v1=fabs(v1);
v2=fabs(v2);
return (v1/(v1+v2))*w1 + (v2/(v1+v2)*w2);
}
For a bit of background, v1 & v2 represent how far two different knobs are turned, the weighting of their individual resultant effects only depends how much they are turned, not in which direction.
Clearly, this has a problem when v1==v2==0, since we end up with return (0/0)*w1 + (0/0)*w2 and you can't do 0/0. Putting a special test in for v1==v2==0 sounds horrible mathematically, even if it wasn't bad practice with floating-point numbers.
So I wondered if
there was a standard library function to handle this
there's a neater mathematical representation
You're trying to implement this mathematical function:
F(x, y) = (W1 * |x| + W2 * |y|) / (|x| + |y|)
This function is discontinuous at the point x = 0, y = 0. Unfortunately, as R. stated in a comment, the discontinuity is not removable - there is no sensible value to use at this point.
This is because the "sensible value" changes depending on the path you take to get to x = 0, y = 0. For example, consider following the path F(0, r) from r = R1 to r = 0 (this is equivalent to having the X knob at zero, and smoothly adjusting the Y knob down from R1 to 0). The value of F(x, y) will be constant at W2 until you get to the discontinuity.
Now consider following F(r, 0) (keeping the Y knob at zero and adjusting the X knob smoothly down to zero) - the output will be constant at W1 until you get to the discontinuity.
Now consider following F(r, r) (keeping both knobs at the same value, and adjusting them down simulatneously to zero). The output here will be constant at W1 + W2 / 2 until you go to the discontinuity.
This implies that any value between W1 and W2 is equally valid as the output at x = 0, y = 0. There's no sensible way to choose between them. (And further, always choosing 0 as the output is completely wrong - the output is otherwise bounded to be on the interval W1..W2 (ie, for any path you approach the discontinuity along, the limit of F() is always within that interval), and 0 might not even lie in this interval!)
You can "fix" the problem by adjusting the function slightly - add a constant (eg 1.0) to both v1 and v2 after the fabs(). This will make it so that the minimum contribution of each knob can't be zero - just "close to zero" (the constant defines how close).
It may be tempting to define this constant as "a very small number", but that will just cause the output to change wildly as the knobs are manipulated close to their zero points, which is probably undesirable.
This is the best I could come up with quickly
float calcWeightedAverage(float v1,float v2,float w1,float w2)
{
float a1 = 0.0;
float a2 = 0.0;
if (v1 != 0)
{
a1 = v1/(v1+v2) * w1;
}
if (v2 != 0)
{
a2 = v2/(v1+v2) * w2;
}
return a1 + a2;
}
I don't see what would be wrong with just doing this:
float calcWeightedAverage( float v1, float v2, float w1, float w2 ) {
static const float eps = FLT_MIN; //Or some other suitably small value.
v1 = fabs( v1 );
v2 = fabs( v2 );
if( v1 + v2 < eps )
return (w1+w2)/2.0f;
else
return (v1/(v1+v2))*w1 + (v2/(v1+v2)*w2);
}
Sure, no "fancy" stuff to figure out your division, but why make it harder than it has to be?
Personally I don't see anything wrong with an explicit check for divide by zero. We all do them, so it could be argued that not having it is uglier.
However, it is possible to turn off the IEEE divide by zero exceptions. How you do this depends on your platform. I know on windows it has to be done process-wide, so you can inadvertantly mess with other threads (and they with you) by doing it if you aren't careful.
However, if you do that your result value will be NaN, not 0. I highly dooubt that's what you want. If you are going to have to put a special check in there anyway with different logic when you get NaN, you might as well just check for 0 in the denominator up front.
So with a weighted average, you need to look at the special case where both are zero. In that case you want to treat it as 0.5 * w1 + 0.5 * w2, right? How about this?
float calcWeightedAverage(float v1,float v2,float w1,float w2)
{
v1=fabs(v1);
v2=fabs(v2);
if (v1 == v2) {
v1 = 0.5;
} else {
v1 = v1 / (v1 + v2); // v1 is between 0 and 1
}
v2 = 1 - v1; // avoid addition and division because they should add to 1
return v1 * w1 + v2 * w2;
}
You chould test for fabs(v1)+fabs(v2)==0 (this seems to be the fastest given that you've already computed them), and return whatever value makes sense in this case (w1+w2/2?). Otherwise, keep the code as-is.
However, I suspect the algorithm itself is broken if v1==v2==0 is possible. This kind of numerical instability when the knobs are "near 0" hardly seems desirable.
If the behavior actually is right and you want to avoid special-cases, you could add the minimum positive floating point value of the given type to v1 and v2 after taking their absolute values. (Note that DBL_MIN and friends are not the correct value because they're the minimum normalized values; you need the minimum of all positive values, including subnormals.) This will have no effect unless they're already extremely small; the additions will just yield v1 and v2 in the usual case.
The problem with using an explicit check for zero is that you can end up with discontinuities in behaviour unless you are careful as outlined in cafs response ( and if its in the core of your algorithm the if can be expensive - but dont care about that until you measure...)
I tend to use something that just smooths out the weighting near zero instead.
float calcWeightedAverage(v1,v2,w1,w2)
{
eps = 1e-7; // Or whatever you like...
v1=fabs(v1)+eps;
v2=fabs(v2)+eps;
return (v1/(v1+v2))*w1 + (v2/(v1+v2)*w2);
}
Your function is now smooth, with no asymptotes or division by zero, and so long as one of v1 or v2 is above 1e-7 by a significant amount it will be indistinguishable from a "real" weighted average.
If the denominator is zero, how do you want it to default? You can do something like this:
static inline float divide_default(float numerator, float denominator, float default) {
return (denominator == 0) ? default : (numerator / denominator);
}
float calcWeightedAverage(v1, v2, w1, w2)
{
v1 = fabs(v1);
v2 = fabs(v2);
return w1 * divide_default(v1, v1 + v2, 0.0) + w2 * divide_default(v2, v1 + v2, 0.0);
}
Note that the function definition and use of static inline should really let the compiler know that it can inline.
This should work
#include <float.h>
float calcWeightedAverage(v1,v2,w1,w2)
{
v1=fabs(v1);
v2=fabs(v2);
return (v1/(v1+v2+FLT_EPSILON))*w1 + (v2/(v1+v2+FLT_EPSILON)*w2);
}
edit:
I saw there may be problems with some precision so instead of using FLT_EPSILON use DBL_EPSILON for accurate results (I guess you will return a float value).
I'd do like this:
float calcWeightedAverage(double v1, double v2, double w1, double w2)
{
v1 = fabs(v1);
v2 = fabs(v2);
/* if both values are equally far from 0 */
if (fabs(v1 - v2) < 0.000000001) return (w1 + w2) / 2;
return (v1*w1 + v2*w2) / (v1 + v2);
}