Module: Jacobian
- Included in:
- Newton
- Defined in:
- lib/bigdecimal/jacobian.rb
Overview
require ‘bigdecimal/jacobian’
Provides methods to compute the Jacobian matrix of a set of equations at a point x. In the methods below:
f is an Object which is used to compute the Jacobian matrix of the equations. It must provide the following methods:
- f.values(x)
-
returns the values of all functions at x
- f.zero
-
returns 0.0
- f.one
-
returns 1.0
- f.two
-
returns 2.0
- f.ten
-
returns 10.0
- f.eps
-
returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
x is the point at which to compute the Jacobian.
fx is f.values(x).
Class Method Summary collapse
-
.dfdxi(f, fx, x, i) ⇒ Object
Computes the derivative of
f[i]
atx[i]
. -
.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.
-
.jacobian(f, fx, x) ⇒ Object
Computes the Jacobian of
f
atx
.
Class Method Details
.dfdxi(f, fx, x, i) ⇒ Object
Computes the derivative of f[i]
at x[i]
. fx
is the value of f
at x
.
47 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 |
# File 'lib/bigdecimal/jacobian.rb', line 47 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
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/bigdecimal/jacobian.rb', line 30 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
.
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/bigdecimal/jacobian.rb', line 79 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 |