Please forgive the longish post, I've tried to boil down a bug to its 
minimum and my hair is now nearly entirely pulled out.

The below code should be executable and requires only the "matrix.rb" 
library that comes with a standard ruby install (At least I think it 
does).

Under certain conditions, if I add a veriable to the script and never 
use it the result of the procedure is changed.  I cannot determin why.

[code]
#!/usr/bin/env ruby
#=Synopsis
#Executable Script for debugging potential ruby floating point and/or 
matrix error
require "matrix"

#Expand the Vector class from Matrix.rb to include:
#  normalize, sum, delta, dot, cross, effectively_equal
#Defaults to a triplet but can contain an n-deminsional vector
#  Currently most of these functions only operate on a 3-deminsional 
vector.

class Vector
  attr :elements, true

  def normalize()
    divisor = 0
    @elements.each do |elem|
      divisor += elem*elem
    end

    if divisor != 0
      divisor = Math.sqrt(divisor);
      i = 0
      @elements.each do |elem|
        @elements[i] /= divisor
        i += 1
      end
    end
  end

  def Vector.normalize(v)
    divisor = 0
    v.elements.each do |elem|
      divisor += elem*elem
    end

    if divisor != 0
      divisor = Math.sqrt(divisor);
      i = 0
      v.elements.each do |elem|
        v.elements[i] /= divisor
        i += 1
      end
    end
    v
  end

  def Vector.sum(u, v)
    newVector = Vector[0,0,0]
    i=0
    u.elements.each do |uElem|
      newVector.elements[i] = uElem.to_f + v.elements[i].to_f
      i += 1
    end
    newVector
  end

  def Vector.delta(u, v)
    newVector = Vector[0,0,0]
    i=0
    # puts "U: #{u} V: #{v}"
    u.elements.each do |uElem|
      newVector.elements[i] = uElem.to_f - v.elements[i].to_f
      i += 1
    end
    newVector
  end

  def Vector.dot(u, v)
    value = 0
    i=0
    u.elements.each do |uElem|
      value += uElem.to_f * v.elements[i].to_f
      i += 1
    end
    value
  end

  def Vector.cross(u, v)
    n = Vector[0,0,0]
    n.elements[0] = u.elements[1].to_f * v.elements[2].to_f - 
u.elements[2].to_f * v.elements[1].to_f
    n.elements[1] = u.elements[2].to_f * v.elements[0].to_f - 
u.elements[0].to_f * v.elements[2].to_f
    n.elements[2] = u.elements[0].to_f * v.elements[1].to_f - 
u.elements[1].to_f * v.elements[0].to_f
    n
  end

  def Vector.effectively_equal(u, v, epsilon = 0.000001)
    i = 0
    eq = TRUE
    u.elements.each do |uElem|
      if uElem.to_f - v.elements[i].to_f > epsilon
        eq = FALSE
      end
      break if not eq
      i += 1
    end
    eq
  end

end # Vector class expansion

# Note, This error occurs when delta of curVert and prevVert have an 
axis of zero.
#       and have a resonably high percision.
curVert = Vector[0.015525, -0.284744, 0.532219]
prevVert = Vector[-0.007794, -0.283622, 0.532219]
nextVert = Vector[0.017021, -0.256189, 0.52561]

puts "-----------"
puts "prevVert \t#{prevVert}"
puts "curVert \t#{curVert}"
puts "nextVert \t#{nextVert}"
a = Vector.delta(prevVert,curVert)
  puts "a: \t\t#{a}"
b0 = Vector.delta(nextVert,curVert)
  puts "b0: \t\t#{b0}"
l = Vector.cross(a,b0)
  puts "l: \t\t#{l}"
l = Vector.normalize(l)
  puts "l normalized: \t#{l}"
a = Vector.normalize(a)
  puts "a normalized: \t#{a}"
b1 = Vector.cross(l,a)
  puts "b1: \t\t#{b1}"

# With b2 uncommented, even though it is not used in any function,
# it changes the output of mInverse by a factor of 2
# - Comment out the two lines below and rerun to see the change in 
mInverse
#--------------v------------
b2 = Vector.normalize(b1)
  puts "b2: \t\t#{b2}"
#--------------^------------

m = Matrix[l.elements,b1.elements,a.elements]
mInverse = m.inverse
  puts "matrix:   \t#{m}"
  puts "mInverse: \t#{mInverse}\n\n"

[/code]

-- 
Posted via http://www.ruby-forum.com/.