Is it me or Math::sqrt?

Discussion in 'Ruby' started by Phillip Gawlowski, Mar 31, 2008.

  1. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Hello list.

    I'm a bit stupefied by the different results of this algorithm I
    implemented (Euclidean distance for 3 dimensions):

    # Calculates the relative distance_to an arbitrary
    # Note: The algorithm is not yet optimized for speed.
    # Hopefully, it is accurate, though.
    def distance_to(actor)
    ~ # Stub, will use vector math or so to approximate the true distance
    ~ distance = (self.x - actor.x)^2 + (self.y - actor.y)^2 + (self.z -
    actor.z)^2
    ~ Math::sqrt(distance.abs)
    end

    actor1 = Gondor::AI::Actor.new:)x => 0,:y => 0,:z => 0)
    actor2 = Gondor::AI::Actor.new:)x => 16, :y => 16, :z => 16)
    actor1.distance(actor2)
    produces: 3.74165738677394

    actor1 = Gondor::AI::Actor.new:)x => 1,:y => 1,:z => 1)
    actor2 = Gondor::AI::Actor.new:)x => 15, :y => 15, :z => 15)
    produces: 4.0

    Why is that? From my understanding, these results should be identical
    (The algebraic sign is eliminated by exponent 2, everything else is
    addition).

    Another thing that has me stumped is, that Math::sqrt requires the
    absolute, but the result should be positive (addition of positive
    algebraic signs).

    Do I need to brush up my math more than I thought?

    - -- Phillip Gawlowski
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.8 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iEYEARECAAYFAkfwsX8ACgkQbtAgaoJTgL+4nwCeJ4ICdvn0ruCpxc9U5OTIjV8y
    OnsAn1nOr6/Fjk0epFFpb3sYgqHoDVhj
    =gHrp
    -----END PGP SIGNATURE-----
     
    Phillip Gawlowski, Mar 31, 2008
    #1
    1. Advertising

  2. 2008/3/31, Phillip Gawlowski <>:
    > -----BEGIN PGP SIGNED MESSAGE-----
    > Hash: SHA1
    >
    > Hello list.
    >
    > I'm a bit stupefied by the different results of this algorithm I
    > implemented (Euclidean distance for 3 dimensions):
    >
    > # Calculates the relative distance_to an arbitrary
    > # Note: The algorithm is not yet optimized for speed.
    > # Hopefully, it is accurate, though.
    > def distance_to(actor)
    > ~ # Stub, will use vector math or so to approximate the true distance
    > ~ distance = (self.x - actor.x)^2 + (self.y - actor.y)^2 + (self.z -
    > actor.z)^2
    > ~ Math::sqrt(distance.abs)
    > end
    >
    > actor1 = Gondor::AI::Actor.new:)x => 0,:y => 0,:z => 0)
    > actor2 = Gondor::AI::Actor.new:)x => 16, :y => 16, :z => 16)
    > actor1.distance(actor2)
    > produces: 3.74165738677394
    >
    > actor1 = Gondor::AI::Actor.new:)x => 1,:y => 1,:z => 1)
    > actor2 = Gondor::AI::Actor.new:)x => 15, :y => 15, :z => 15)
    > produces: 4.0
    >
    > Why is that? From my understanding, these results should be identical
    > (The algebraic sign is eliminated by exponent 2, everything else is
    > addition).
    >
    > Another thing that has me stumped is, that Math::sqrt requires the
    > absolute, but the result should be positive (addition of positive
    > algebraic signs).
    >
    > Do I need to brush up my math more than I thought?
    >
    > - -- Phillip Gawlowski
    > -----BEGIN PGP SIGNATURE-----
    > Version: GnuPG v1.4.8 (MingW32)
    > Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
    >
    > iEYEARECAAYFAkfwsX8ACgkQbtAgaoJTgL+4nwCeJ4ICdvn0ruCpxc9U5OTIjV8y
    > OnsAn1nOr6/Fjk0epFFpb3sYgqHoDVhj
    > =gHrp
    > -----END PGP SIGNATURE-----


    - without words -

    irb(main):002:0> (0-16)^2
    => -14
    irb(main):003:0> (0-16) ** 2
    => 256

    :)

    Kind regards

    robert

    --
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Mar 31, 2008
    #2
    1. Advertising

  3. Phillip Gawlowski wrote:
    > actor1 = Gondor::AI::Actor.new:)x => 0,:y => 0,:z => 0)
    > actor2 = Gondor::AI::Actor.new:)x => 16, :y => 16, :z => 16)
    > actor1.distance(actor2)
    > produces: 3.74165738677394
    >
    > actor1 = Gondor::AI::Actor.new:)x => 1,:y => 1,:z => 1)
    > actor2 = Gondor::AI::Actor.new:)x => 15, :y => 15, :z => 15)
    > produces: 4.0
    >
    > Why is that? From my understanding, these results should be identical
    > (The algebraic sign is eliminated by exponent 2, everything else is
    > addition).


    If my reading is correct the distances should be different. I am not
    saying that the reported distances are correct only that they should be
    different. Take the x axis for example:

    (0 - 16) * (0 - 16) = 256
    (1 - 15) * (1 - 15) = 196

    What you probably meant was:

    actor1 = Gondor::AI::Actor.new:)x => 0,:y => 0,:z => 0)
    actor2 = Gondor::AI::Actor.new:)x => 15, :y => 15, :z => 15)

    should be the same distance as:

    actor1 = Gondor::AI::Actor.new:)x => 1,:y => 1,:z => 1)
    actor2 = Gondor::AI::Actor.new:)x => 16, :y => 16, :z => 16)
     
    Peter Hickman, Mar 31, 2008
    #3
  4. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Robert Klemme wrote:
    | 2008/3/31, Phillip Gawlowski <>:
    |> # Calculates the relative distance_to an arbitrary
    |> # Note: The algorithm is not yet optimized for speed.
    |> # Hopefully, it is accurate, though.
    |> def distance_to(actor)
    |> # Stub, will use vector math or so to approximate the true distance
    |> distance = (self.x - actor.x)^2 + (self.y - actor.y)^2 + (self.z -
    |> actor.z)^2
    |> Math::sqrt(distance.abs)
    |> end
    |>
    |> actor1 = Gondor::AI::Actor.new:)x => 0,:y => 0,:z => 0)
    |> actor2 = Gondor::AI::Actor.new:)x => 16, :y => 16, :z => 16)
    |> actor1.distance(actor2)
    |> produces: 3.74165738677394
    |>
    |> actor1 = Gondor::AI::Actor.new:)x => 1,:y => 1,:z => 1)
    |> actor2 = Gondor::AI::Actor.new:)x => 15, :y => 15, :z => 15)
    |> produces: 4.0
    |>
    |> Why is that? From my understanding, these results should be identical
    |> (The algebraic sign is eliminated by exponent 2, everything else is
    |> addition).
    |>
    |> Another thing that has me stumped is, that Math::sqrt requires the
    |> absolute, but the result should be positive (addition of positive
    |> algebraic signs).
    |>
    |> Do I need to brush up my math more than I thought?
    |
    | - without words -
    |
    | irb(main):002:0> (0-16)^2
    | => -14
    | irb(main):003:0> (0-16) ** 2
    | => 256
    |
    | :)
    |
    | Kind regards
    |
    | robert
    |

    I've replaced ^2 with ** 2, but that doesn't seem to change the
    magnitude of the error (Though, the results "feels" more correct now, so
    thanks for that).

    The results are still different, as you can see:
    24.2487113059643 for actor1's x,y,z = 1, and actor2's x,y,z = 15
    27.712812921102 for actor1's x,y,z = 0, and actor2's x,y,z = 16

    However, since the coordinates are subtracted on their respective
    axises, I guess that my assumption on the "error" is incorrect, and that
    I do get the correct value. However, intuitively, the distance between
    these two points should be the same. Hmmmm..

    - -- Phillip Gawlowski
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.8 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iEYEARECAAYFAkfwtewACgkQbtAgaoJTgL+8oACfelpzNMjMyhvl6x4tfJi6M/2f
    /m4AnA0T46orBD6hnv7g6YCsb60PZdzC
    =ANtA
    -----END PGP SIGNATURE-----
     
    Phillip Gawlowski, Mar 31, 2008
    #4
  5. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Peter Hickman wrote:

    |
    | If my reading is correct the distances should be different. I am not
    | saying that the reported distances are correct only that they should be
    | different. Take the x axis for example:
    |
    | (0 - 16) * (0 - 16) = 256
    | (1 - 15) * (1 - 15) = 196
    |
    | What you probably meant was:
    |
    | actor1 = Gondor::AI::Actor.new:)x => 0,:y => 0,:z => 0)
    | actor2 = Gondor::AI::Actor.new:)x => 15, :y => 15, :z => 15)
    |
    | should be the same distance as:
    |
    | actor1 = Gondor::AI::Actor.new:)x => 1,:y => 1,:z => 1)
    | actor2 = Gondor::AI::Actor.new:)x => 16, :y => 16, :z => 16)


    D'oh. Forrest, meet trees. Yes, that is what I should check on, and
    nothing else. Thank you for that reality check.

    - --Phillip Gawlowski
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.8 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iEYEARECAAYFAkfwtuMACgkQbtAgaoJTgL+UygCfQ1G2niZu4G60imSxX5jfPIIP
    TbYAn01cHltyBoe/Y3djzHiHCmDwSYGs
    =8QBe
    -----END PGP SIGNATURE-----
     
    Phillip Gawlowski, Mar 31, 2008
    #5
  6. 2008/3/31, Phillip Gawlowski <>:
    > I've replaced ^2 with ** 2, but that doesn't seem to change the
    > magnitude of the error (Though, the results "feels" more correct now, so
    > thanks for that).


    Is this really true after Peter's response? Looks ok to me:

    irb(main):001:0> Math.sqrt(3 * (16-1)**2)
    => 25.9807621135332
    irb(main):002:0> Math.sqrt(3 * (15-0)**2)
    => 25.9807621135332

    Cheers

    robert

    --
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Mar 31, 2008
    #6
  7. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Robert Klemme wrote:
    | 2008/3/31, Phillip Gawlowski <>:
    |> I've replaced ^2 with ** 2, but that doesn't seem to change the
    |> magnitude of the error (Though, the results "feels" more correct now, so
    |> thanks for that).
    |
    | Is this really true after Peter's response? Looks ok to me:
    |
    | irb(main):001:0> Math.sqrt(3 * (16-1)**2)
    | => 25.9807621135332
    | irb(main):002:0> Math.sqrt(3 * (15-0)**2)
    | => 25.9807621135332

    Yeah, the mistake was clearly mine. Fixing my assumption helped with
    fixing the bug. Though, this time the bug was a PBKAC.

    A hint should've been that I needed Fixnum#abs to properly calculate the
    square root required by the algorithm.

    Which shows that flying solo has its dangers.

    Thanks for correcting me. :)

    - -- Phillip Gawlowski
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.8 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iEYEARECAAYFAkfw2WIACgkQbtAgaoJTgL/mEACdFRpZKC3v4DxJa2+lDodoGYuN
    wLcAn13rWNycC4RCnn7V2YeZeR6UQ8vI
    =5Iq9
    -----END PGP SIGNATURE-----
     
    Phillip Gawlowski, Mar 31, 2008
    #7
  8. 2008/3/31, Phillip Gawlowski <>:
    > Yeah, the mistake was clearly mine. Fixing my assumption helped with
    > fixing the bug. Though, this time the bug was a PBKAC.
    >
    > A hint should've been that I needed Fixnum#abs to properly calculate the
    > square root required by the algorithm.


    Yes, that was what got me wondering.

    > Which shows that flying solo has its dangers.


    Often it's helpful to try parts of an algorithm in IRB. That way you
    easily find bugs as this one. :)

    Kind regards

    robert

    --
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Mar 31, 2008
    #8
  9. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Robert Klemme wrote:
    | 2008/3/31, Phillip Gawlowski <>:
    |
    | Often it's helpful to try parts of an algorithm in IRB. That way you
    | easily find bugs as this one. :)

    The difficulty is, that my assumptions were broken. And even with irb,
    the assumptions *I* make aren't checked. Neither would unit tests or
    similar things: If my assumptions are incorrect, and I don't know it,
    I'll write tests and code that validate my assumptions.

    The difficulty, if one is working alone, to find a way to check
    assumptions (and looking up the math formula for calculating the
    Euclidean distance between two points helped my catch another assumption
    I made, fortunately), which co-workers or so could provide.

    Ah, well, this just shows that I have to check my assumptions, too, and
    perform due diligence when working on something. Which is blatantly
    obvious, of course, but I needed that reminder, obviously.

    I'm just glad that I only write code in a vacuum, but don't exist in one. :p


    - -- Phillip Gawlowski
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.8 (MingW32)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iEYEARECAAYFAkfw3kYACgkQbtAgaoJTgL+lHwCfRmMN9JLjszwU0S+s+au4cJPc
    l20AnRTtcp2y4kygn++M8Dbadxw2DrLE
    =v+RD
    -----END PGP SIGNATURE-----
     
    Phillip Gawlowski, Mar 31, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. LeTubs

    math.h problem -> sqrt undefined

    LeTubs, Jun 25, 2004, in forum: C Programming
    Replies:
    3
    Views:
    2,572
  2. Tim Roberts
    Replies:
    2
    Views:
    275
    Eric Kemp
    Jan 4, 2009
  3. Chris Angelico
    Replies:
    2
    Views:
    383
    John Nagle
    Jul 23, 2011
  4. Simon Strandgaard

    Math.sqrt(-1) doesn't raise ArgumentError

    Simon Strandgaard, Feb 16, 2004, in forum: Ruby
    Replies:
    4
    Views:
    140
    Josef 'Jupp' SCHUGT
    Feb 16, 2004
  5. VK
    Replies:
    15
    Views:
    1,286
    Dr J R Stockton
    May 2, 2010
Loading...

Share This Page