Module: Jacobian

Included in:
Newton
Defined in:
lib/bigdecimal/jacobian.rb

Class Method Summary collapse

Class Method Details

.dfdxi(f, fx, x, i) ⇒ Object

Computes the derivative of f at x. fx is the value of f at x.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/bigdecimal/jacobian.rb', line 48

def dfdxi(f,fx,x,i)
  nRetry = 0
  n = x.size
  xSave = x[i]
  ok = 0
  ratio = f.ten*f.ten*f.ten
  dx = x[i].abs/ratio
  dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
  dx = f.one/f.ten     if isEqual(dx,f.zero,f.zero,f.eps)
  until ok>0 do
    deriv = []
    nRetry += 1
    if nRetry > 100
      raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
    end
    dx = dx*f.two
    x[i] += dx
    fxNew = f.values(x)
    for j in 0...n do
      if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
        ok += 1
        deriv <<= (fxNew[j]-fx[j])/dx
      else
        deriv <<= f.zero
      end
    end
    x[i] = xSave
  end
  deriv
end

.isEqual(a, b, zero = 0.0, e = 1.0e-8) ⇒ Object

Determines the equality of two numbers by comparing to zero, or using the epsilon value



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/bigdecimal/jacobian.rb', line 31

def isEqual(a,b,zero=0.0,e=1.0e-8)
  aa = a.abs
  bb = b.abs
  if aa == zero &&  bb == zero then
    true
  else
    if ((a-b)/(aa+bb)).abs < e then
      true
    else
      false
    end
  end
end

.jacobian(f, fx, x) ⇒ Object

Computes the Jacobian of f at x. fx is the value of f at x.



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/bigdecimal/jacobian.rb', line 80

def jacobian(f,fx,x)
  n = x.size
  dfdx = Array.new(n*n)
  for i in 0...n do
    df = dfdxi(f,fx,x,i)
    for j in 0...n do
      dfdx[j*n+i] = df[j]
    end
  end
  dfdx
end