Re: phypot - Pygmy Hippotause ?

Lists: pgsql-hackers
From: Paul Matthews <plm(at)netspace(dot)net(dot)au>
To: pgsql-hackers(at)postgresql(dot)org
Subject: phypot - Pygmy Hippotause ?
Date: 2009-08-28 08:53:24
Message-ID: 4A979B04.4030500@netspace.net.au
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Another attempt at replacing the current HYPOT macro with a much better
behaved function. I've added comments addressing those sections of code
that tripped people up before. As well as explaining some of the design
decisions. Feedback appreciated.

Attachment Content-Type Size
patchfile_phypot text/plain 5.7 KB

From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Paul Matthews" <plm(at)netspace(dot)net(dot)au>, <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: phypot - Pygmy Hippotause ?
Date: 2009-08-28 15:02:01
Message-ID: 4A97AB19020000250002A4EA@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Paul Matthews <plm(at)netspace(dot)net(dot)au> wrote:
> Feedback appreciated.

+ /* As x is the larger value, this must be the correct answer.
Also
+ * avoids division by zero. */
+ if( x == 0.0 )
+ return 0.0;
+
+ /* Trivial case. */
+ if( y == 0.0 )
+ return x;

The first test seems unnecessary if you have the second.
x >= 0, so x can't be zero unless y is, too.
Returning x on y == 0.0 will return 0.0 whenever x == 0.0.

-Kevin


From: Paul Matthews <plm(at)netspace(dot)net(dot)au>
To: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: phypot - Pygmy Hippotause ?
Date: 2009-08-29 02:52:17
Message-ID: 4A9897E1.8090703@netspace.net.au
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Kevin Grittner wrote:
>
> The first test seems unnecessary if you have the second.
> x >= 0, so x can't be zero unless y is, too.
> Returning x on y == 0.0 will return 0.0 whenever x == 0.0.
>
> -Kevin
>
Wish granted. :-)

--
--
Fools ignore complexity. Pragmatists suffer it.
Some can avoid it. Geniuses remove it.

Attachment Content-Type Size
patchfile_phypot text/plain 5.7 KB

From: Bruce Momjian <bruce(at)momjian(dot)us>
To: Paul Matthews <plm(at)netspace(dot)net(dot)au>
Cc: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: phypot - Pygmy Hippotause ?
Date: 2010-02-23 05:46:29
Message-ID: 201002230546.o1N5kTT08988@momjian.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers


I assume this is not something we are supposed to apply.

---------------------------------------------------------------------------

Paul Matthews wrote:
> Kevin Grittner wrote:
> >
> > The first test seems unnecessary if you have the second.
> > x >= 0, so x can't be zero unless y is, too.
> > Returning x on y == 0.0 will return 0.0 whenever x == 0.0.
> >
> > -Kevin
> >
> Wish granted. :-)
>
> --
> --
> Fools ignore complexity. Pragmatists suffer it.
> Some can avoid it. Geniuses remove it.
>

> Index: src/backend/utils/adt/geo_ops.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v
> retrieving revision 1.103
> diff -c -r1.103 geo_ops.c
> *** src/backend/utils/adt/geo_ops.c 28 Jul 2009 09:47:59 -0000 1.103
> --- src/backend/utils/adt/geo_ops.c 29 Aug 2009 02:47:14 -0000
> ***************
> *** 32,37 ****
> --- 32,38 ----
> * Internal routines
> */
>
> + static double phypot(double x, double y);
> static int point_inside(Point *p, int npts, Point *plist);
> static int lseg_crossing(double x, double y, double px, double py);
> static BOX *box_construct(double x1, double x2, double y1, double y2);
> ***************
> *** 825,831 ****
> box_cn(&a, box1);
> box_cn(&b, box2);
>
> ! PG_RETURN_FLOAT8(HYPOT(a.x - b.x, a.y - b.y));
> }
>
>
> --- 826,832 ----
> box_cn(&a, box1);
> box_cn(&b, box2);
>
> ! PG_RETURN_FLOAT8(phypot(a.x-b.x, a.y-b.y));
> }
>
>
> ***************
> *** 1971,1977 ****
> Point *pt1 = PG_GETARG_POINT_P(0);
> Point *pt2 = PG_GETARG_POINT_P(1);
>
> ! PG_RETURN_FLOAT8(HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));
> }
>
> double
> --- 1972,1978 ----
> Point *pt1 = PG_GETARG_POINT_P(0);
> Point *pt2 = PG_GETARG_POINT_P(1);
>
> ! PG_RETURN_FLOAT8(phypot(pt1->x - pt2->x, pt1->y - pt2->y));
> }
>
> double
> ***************
> *** 1979,1987 ****
> {
> #ifdef GEODEBUG
> printf("point_dt- segment (%f,%f),(%f,%f) length is %f\n",
> ! pt1->x, pt1->y, pt2->x, pt2->y, HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));
> #endif
> ! return HYPOT(pt1->x - pt2->x, pt1->y - pt2->y);
> }
>
> Datum
> --- 1980,1988 ----
> {
> #ifdef GEODEBUG
> printf("point_dt- segment (%f,%f),(%f,%f) length is %f\n",
> ! pt1->x, pt1->y, pt2->x, pt2->y, phypot(pt1->x - pt2->x, pt1->y - pt2->y));
> #endif
> ! return phypot(pt1->x - pt2->x, pt1->y - pt2->y);
> }
>
> Datum
> ***************
> *** 2444,2450 ****
> dist_pl_internal(Point *pt, LINE *line)
> {
> return (line->A * pt->x + line->B * pt->y + line->C) /
> ! HYPOT(line->A, line->B);
> }
>
> Datum
> --- 2445,2451 ----
> dist_pl_internal(Point *pt, LINE *line)
> {
> return (line->A * pt->x + line->B * pt->y + line->C) /
> ! phypot(line->A, line->B);
> }
>
> Datum
> ***************
> *** 4916,4922 ****
> PointPGetDatum(point)));
> result->center.x = p->x;
> result->center.y = p->y;
> ! result->radius *= HYPOT(point->x, point->y);
>
> PG_RETURN_CIRCLE_P(result);
> }
> --- 4917,4923 ----
> PointPGetDatum(point)));
> result->center.x = p->x;
> result->center.y = p->y;
> ! result->radius *= phypot(point->x, point->y);
>
> PG_RETURN_CIRCLE_P(result);
> }
> ***************
> *** 4936,4942 ****
> PointPGetDatum(point)));
> result->center.x = p->x;
> result->center.y = p->y;
> ! result->radius /= HYPOT(point->x, point->y);
>
> PG_RETURN_CIRCLE_P(result);
> }
> --- 4937,4943 ----
> PointPGetDatum(point)));
> result->center.x = p->x;
> result->center.y = p->y;
> ! result->radius /= phypot(point->x, point->y);
>
> PG_RETURN_CIRCLE_P(result);
> }
> ***************
> *** 5401,5403 ****
> --- 5402,5465 ----
>
> return FALSE;
> }
> +
> +
> + /*-------------------------------------------------------------------------
> + * Determine the hypotenuse.
> + *
> + * If required, x and y are swapped to make x the larger number. The
> + * traditional formulae of x^2+y^2 is rearranged to factor x outside the
> + * sqrt. This allows computation of the hypotenuse for significantly
> + * larger values, and with a higher precision than otherwise normally
> + * possible.
> + *
> + * Only arguments of > 1.27e308 are at risk of causing overflow. Whereas
> + * the naive approach limits arguments to < 9.5e153.
> + *
> + * sqrt( x^2 + y^2 ) = sqrt( x^2( 1 + y^2/x^2) )
> + * = x * sqrt( 1 + y^2/x^2 )
> + * = x * sqrt( 1 + y/x * y/x )
> + *
> + * It is expected that this routine will eventually be replaced with the
> + * C99 hypot() function.
> + *
> + * This implementation conforms to IEEE Std 1003.1 and GLIBC, in that the
> + * case of hypot(inf,nan) results in INF, and not NAN. To obtain Single
> + * UNIX Specification behaviour, swap the order of the isnan() and isinf()
> + * test sections.
> + *
> + * The HYPOT macro this function is replacing did not check for, or
> + * signal on overflow. In addition no part of geo_ops checks for overflow,
> + * underflow or NaN's. This function maintains the same behaviour.
> + *-----------------------------------------------------------------------*/
> + double phypot( double x, double y )
> + {
> + double yx;
> +
> + /* As per IEEE Std 1003.1 */
> + if( isinf(x) || isinf(y) )
> + return get_float8_infinity();
> +
> + /* As per IEEE Std 1003.1 */
> + if( isnan(x) || isnan(y) )
> + return get_float8_nan();
> +
> + /* If required, swap x and y */
> + x = fabs(x);
> + y = fabs(y);
> + if (x < y) {
> + double temp = x;
> + x = y;
> + y = temp;
> + }
> +
> + /* If x is also 0.0, then 0.0 is returned. This is the correct result
> + * and avoids division by zero. When x > 0.0 we can trivially avoid
> + * the calculation of the hypotenuse. */
> + if( y == 0.0 )
> + return x;
> +
> + /* Determine the hypotenuse */
> + yx = y/x;
> + return x*sqrt(1.0+yx*yx);
> + }
> Index: src/include/utils/geo_decls.h
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/include/utils/geo_decls.h,v
> retrieving revision 1.55
> diff -c -r1.55 geo_decls.h
> *** src/include/utils/geo_decls.h 1 Jan 2009 17:24:02 -0000 1.55
> --- src/include/utils/geo_decls.h 29 Aug 2009 02:47:19 -0000
> ***************
> *** 50,56 ****
> #define FPge(A,B) ((A) >= (B))
> #endif
>
> - #define HYPOT(A, B) sqrt((A) * (A) + (B) * (B))
>
> /*---------------------------------------------------------------------
> * Point - (x,y)
> --- 50,55 ----

>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers

--
Bruce Momjian <bruce(at)momjian(dot)us> http://momjian.us
EnterpriseDB http://enterprisedb.com
PG East: http://www.enterprisedb.com/community/nav-pg-east-2010.do
+ If your life is a hard drive, Christ can be your backup. +


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Bruce Momjian" <bruce(at)momjian(dot)us>, "Paul Matthews" <plm(at)netspace(dot)net(dot)au>
Cc: <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: phypot - Pygmy Hippotause ?
Date: 2010-02-23 21:03:13
Message-ID: 4B83EE31020000250002F55E@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Bruce Momjian <bruce(at)momjian(dot)us> wrote:

> I assume this is not something we are supposed to apply.

While it appears to improve conformance with the IEEE Std 1003.1 and
expand the range of numbers which are correctly handled, it does
more calculations. I wouldn't want to see it get in without
performance testing and confirmation that existing apps don't rely
on the non-standard behavior. I don't remember either of those
happening.

-Kevin


From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Kevin Grittner <Kevin(dot)Grittner(at)wicourts(dot)gov>
Cc: Bruce Momjian <bruce(at)momjian(dot)us>, Paul Matthews <plm(at)netspace(dot)net(dot)au>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: phypot - Pygmy Hippotause ?
Date: 2010-02-23 22:04:28
Message-ID: 603c8f071002231404t4d90e8c2vf1fce300b1af6d72@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, Feb 23, 2010 at 4:03 PM, Kevin Grittner
<Kevin(dot)Grittner(at)wicourts(dot)gov> wrote:
> Bruce Momjian <bruce(at)momjian(dot)us> wrote:
>> I assume this is not something we are supposed to apply.
>
> While it appears to improve conformance with the IEEE Std 1003.1 and
> expand the range of numbers which are correctly handled, it does
> more calculations.  I wouldn't want to see it get in without
> performance testing and confirmation that existing apps don't rely
> on the non-standard behavior.  I don't remember either of those
> happening.

Perhaps we should add it to the next CommitFest?

...Robert


From: "Kevin Grittner" <Kevin(dot)Grittner(at)wicourts(dot)gov>
To: "Robert Haas" <robertmhaas(at)gmail(dot)com>
Cc: "Bruce Momjian" <bruce(at)momjian(dot)us>, "Paul Matthews" <plm(at)netspace(dot)net(dot)au>, <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: phypot - Pygmy Hippotause ?
Date: 2010-02-23 22:36:30
Message-ID: 4B84040E020000250002F58F@gw.wicourts.gov
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Robert Haas <robertmhaas(at)gmail(dot)com> wrote:

> Perhaps we should add it to the next CommitFest?

Sounds like the right course of action to me. If nobody objects or
beats me to it, I'll do that.

-Kevin