delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2016/01/05/23:51:23

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
Date: Wed, 6 Jan 2016 05:53:54 +0100 (CET)
X-X-Sender: igor2 AT igor2priv
To: "Britton Kerin (britton DOT kerin AT gmail DOT com) [via geda-user AT delorie DOT com]" <geda-user AT delorie DOT com>
X-Debug: to=geda-user AT delorie DOT com from="gedau AT igor2 DOT repo DOT hu"
From: gedau AT igor2 DOT repo DOT hu
Subject: Re: [geda-user] Re: some more geometry module tweaks (sorry, wall
of text)
In-Reply-To: <CAC4O8c8Or1FS=x18C7Zv5uu+dUOXX2My4K+njsoufNeotm_CBQ@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1601060519350.9035@igor2priv>
References: <CAC4O8c-n4cHWum2MUzgDw=NLuKPK395xp_F24cSyoXhnADRskw AT mail DOT gmail DOT com> <alpine DOT DEB DOT 2 DOT 00 DOT 1512230503390 DOT 9035 AT igor2priv> <CAC4O8c8A271d5unQWRV=PoaEsJECgZt33Wy16uCnK6D+4LCzww AT mail DOT gmail DOT com> <alpine DOT DEB DOT 2 DOT 00 DOT 1512260402081 DOT 9035 AT igor2priv>
<CAC4O8c-49Fn191KT-p0hXi1jXW=OeTSaNUh11pLmBQYHeGtyoA AT mail DOT gmail DOT com> <alpine DOT DEB DOT 2 DOT 00 DOT 1512310512510 DOT 9035 AT igor2priv> <CAC4O8c8Or1FS=x18C7Zv5uu+dUOXX2My4K+njsoufNeotm_CBQ AT mail DOT gmail DOT com>
User-Agent: Alpine 2.00 (DEB 1167 2008-08-23)
MIME-Version: 1.0
Reply-To: geda-user AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: geda-user AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--0-950131089-1452056034=:9035
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE



On Tue, 5 Jan 2016, Britton Kerin (britton DOT kerin AT gmail DOT com) [via geda-user@=
delorie.com] wrote:

>
>Igor and I have been discussing pcb geometry kernel design, I'm ccing the
>list in case anyone has strong opinions.
>
>[snip]
>
>      Question is: should a big geometry refactoring fix old bugs or
>      questionalbe numeric conversions or just do the same thing with
>      different code org?
>
>      For all the time, I assumed the first.
>
>
>I agree, but we may have different ideas of what the fix would be.=C2=A0 I=
f you
>want to stop using floating point entirely, it's a huge effort, and ints
>won't do what you want either, you need rationals.=C2=A0 If by fix you mea=
n

Although later part of the mail had a list like this, that doesn't include=
=20
rationals so I'll repeat it for those who didn't have the chance=20
to follow our conversation. The options I currently see:

1. go for maximal precision, be theoretically/mathematically correct in=20
all situations, no rounding ever: rationals.

2. live with imperfection, and don't care too much where it lurks as long=
=20
as the code generally works (I believe this is how most of the code=20
worked in the past)

3. live with imperfection, but try to explicitly nail it down to make sure=
=20
it's under control

3.a. use integers: easier to use non-native wider types, less hidden=20
global states than with floats; but gets hard with very small numbers

3.b. use floats: they are native, small numbers are easy; it may take more=
=20
effort to explicitly control corner cases, and corners may sligtly break=20
on different arch

I think 1 is overkill. I also think long term 3 should be the goal. I=20
also think it is totally realistic that the path goes through 2: first=20
collect the calculations somehwere central reorganizing the code, then=20
deal with the corners.

So I don't think integer is the ultimate solution. I only say that=20
assuming doubles will just work leads to point 2., not point 3.b. I=20
remember your code made efforts to get rounding correctly, so it's clearly=
=20
not the case. And this leads to my next conjecture: I think doing 3.b.=20
properly is not substantially easier than getting 3.a. corrctly. Where=20
the rounding/conversion is implememented is orthogonal to this. So I=20
probably wouldn't close the door on 3.a.

>acknowlege intrinsic issues like https://bugs.launchpad.net/pcb/+bug/10133=
58
>and explain how users can avoid them, that's what I think would be good.=
=C2=A0 So
>then it just becomes a matter of where you actually put the=C2=A0
>conversions.=C2=A0 At the boundary of an all-floating point math kernel is=
 one
>logical place...

I agree. Another logical place is an all-integer math API so that the=20
conversion/fix-for-3 is hidden behind the API. Both solutions could work,=
=20
I happen the prefer the latter.

<snip>
>Hmm.=C2=A0 I had intended the geometry.h as a sort of portable source libr=
ary,
>without any encapsulated pcb-specific decisions.=C2=A0 As it happens I alr=
eady
>have pcb_geometry.h as well which does some adaptation.=C2=A0 Perhaps the =
latter
>just needs to grow a bit, at which point our ideas of how to handle this a=
re
>probably about the same.

Sounds good. I'll start "drawing" because I am not sure I can follow the=20
details. Upper libs depend on lower libs.

A pcb
B pcb-specific-geo (often with complex pcb types)
C generic-geo

So you say C does everything in floating point, and B is responsible for=20
proper rounding/conversions? Or did I get the whole stack wrong?




<snip>
>Here's one attempt at a general approach to this problem:
>
>http://www.gnu.org/software/gsl/manual/html_node/Approximate-Comparison-of=
-
>Floating-Point-Numbers.html#Approximate-Comparison-of-Floating-Point-Numbe=
r
>s

Nice!

<snip>
>I'm not sure about this.=C2=A0 A wider float type can actually represent
>everything in a narrower int type.=C2=A0 Consider:
>
>=C2=A0 =C2=A0 =C2=A0#include <float.h>
>=C2=A0 =C2=A0 =C2=A0#include <stdint.h>
>=C2=A0 =C2=A0 =C2=A0#include <math.h>
>=C2=A0 =C2=A0 =C2=A0#include <stdio.h>
>=C2=A0=C2=A0
>=C2=A0 =C2=A0 =C2=A0int
>=C2=A0 =C2=A0 =C2=A0main (void)
>=C2=A0 =C2=A0 =C2=A0{
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "INT32_MAX: =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0%i\n", INT32=
_MAX);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"pow (FLT_RADIX, DBL_MANT_DIG) - =
1: =C2=A0%f\n",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) - 1=
 );
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"pow (FLT_RADIX, DBL_MANT_DIG): =
=C2=A0 =C2=A0 =C2=A0%f\n",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) );
>=C2=A0 =C2=A0 =C2=A0 =C2=A0printf (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"pow (FLT_RADIX, DBL_MANT_DIG) + =
1: =C2=A0%f\n",
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) + 1=
 );
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>=C2=A0 =C2=A0 =C2=A0}
>
>which gives:
>
>=C2=A0 =C2=A0 =C2=A0 $ gcc --std=3Dc11 -Wall -Wextra -Werror text.c=C2=A0
>=C2=A0 =C2=A0 =C2=A0 $ ./a.out=C2=A0
>=C2=A0 =C2=A0 =C2=A0 INT32_MAX: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A02147483647
>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) - 1: =C2=A09007199254740=
991.000000
>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG): =C2=A0 =C2=A0 =C2=A0900=
7199254740992.000000
>=C2=A0 =C2=A0 =C2=A0pow (FLT_RADIX, DBL_MANT_DIG) + 1: =C2=A09007199254740=
992.000000
>=C2=A0 =C2=A0 =C2=A0$=C2=A0
>
>The largest double to which you can count "by ones" is much greater than
>INT32_MAX.

<snip>

>Yes, the relationship must be such that e.g.=C2=A0pow (FLT_RADIX, DBL_MANT=
_DIG) >
>INT32_MAX (or whatever largest coord you want to handle), or else you have
>to worry about the exact consequences for every case (impractical).


Yup, this is generally true, and double has more bits than int32. However,=
=20
I think you should also cosinder the x^2 cases: what happens to an=20
sqrt(x^2), if x^2 was in the range of 2^31?

Note: on a PC, intermediate float/double calculations are often done usign=
=20
80 bits instead of 64 or 32. This can forge some of the "where floats=20
break" tests. There's a gcc switch (I can't remember this morning) to=20
force using the smaller types, or to use software emulated fp.

<snip>
>My claim on this is that if your float type entirely contains the set of
>your int type, there's no doubt about how the conversion in one direction
>should work.=C2=A0 I agree that when you round a result to snap back to th=
e int
>grid there's no escaping thinking about which way you should round given t=
he
>context, which is why a general rounding policy might not work.=C2=A0 On t=
he
>other hand giving up automatic rounding for correctness on that last 1 nm
>might be insane.=C2=A0 If your overall design depends on that you have pro=
blems
>anyway.=C2=A0 For example pcb, should probably be honest and somehow tell =
the
>user that setting DRC clearance, line width, and grid size all the same is
>more or less guaranteed to blow up, despite the theoretical correctness.

I agree, design depending on 1 nm is plain wrong.

However, I wouldn't like to see my pcb file showing a 10k diff because I=20
some innocent operation pused things around in the 1nm range as a side=20
effect. This why I am concerned about round trips of the calculations.

Regards,

Igor2
--0-950131089-1452056034=:9035--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019