stick 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +3 -4
- data/README +1 -1
- data/lib/stick/constants/cgs.rb +112 -110
- data/lib/stick/constants/mks.rb +6 -4
- data/lib/stick/constants/number.rb +3 -2
- data/lib/stick/constants/typeless_cgs.rb +105 -106
- data/lib/stick/constants/typeless_mks.rb +106 -107
- data/lib/stick/currency.rb +2 -0
- data/lib/stick/mapcar.rb +36 -23
- data/lib/stick/matrix.rb +10 -395
- data/lib/stick/matrix/core.rb +1408 -0
- data/lib/stick/matrix/exception.rb +23 -0
- data/lib/stick/matrix/givens.rb +59 -0
- data/lib/stick/matrix/hessenberg.rb +63 -0
- data/lib/stick/matrix/householder.rb +106 -0
- data/lib/stick/matrix/jacobi.rb +106 -0
- data/lib/stick/matrix/lu.rb +60 -0
- data/lib/stick/quaternion.rb +10 -6
- data/lib/stick/units.rb +2 -0
- data/lib/stick/units/base.rb +75 -72
- data/lib/stick/units/currency.rb +8 -8
- data/lib/stick/units/loaders.rb +3 -2
- data/lib/stick/units/units.rb +2 -0
- data/lib/stick/vector.rb +20 -0
- data/meta/MANIFEST +23 -3
- data/meta/stick.roll +1 -1
- data/task/tests/solo +293 -0
- data/test/spec_matrix.rb +3 -0
- data/test/test_constants.rb +4 -0
- data/test/test_currency.rb +2 -2
- data/test/test_matrix.rb +7 -1
- data/test/test_units.rb +2 -2
- metadata +15 -2
@@ -14,115 +14,114 @@
|
|
14
14
|
# - Daniel Carrera
|
15
15
|
# - Brian Gough
|
16
16
|
|
17
|
-
|
17
|
+
module Stick #:nodoc:
|
18
18
|
module Constants
|
19
|
+
module Typeless
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
# Unitless constants in the MKS system (meters, kg, sec)
|
23
|
-
|
24
|
-
module MKS
|
25
|
-
SPEED_OF_LIGHT = 2.99792458e8 # m / s
|
26
|
-
GRAVITATIONAL_CONSTANT = 6.673e-11 # m^3 / kg s^2
|
27
|
-
PLANCKS_CONSTANT_H = 6.62606876e-34 # kg m^2 / s
|
28
|
-
PLANCKS_CONSTANT_HBAR = 1.05457159642e-34 # kg m^2 / s
|
29
|
-
VACUUM_PERMEABILITY = 1.25663706144e-6 # kg m / A^2 s^2
|
30
|
-
ASTRONOMICAL_UNIT = 1.49597870691e11 # m
|
31
|
-
LIGHT_YEAR = 9.46053620707e15 # m
|
32
|
-
PARSEC = 3.08567758135e16 # m
|
33
|
-
GRAV_ACCEL = 9.80665e0 # m / s^2
|
34
|
-
ELECTRON_VOLT = 1.602176462e-19 # kg m^2 / s^2
|
35
|
-
MASS_ELECTRON = 9.10938188e-31 # kg
|
36
|
-
MASS_MUON = 1.88353109e-28 # kg
|
37
|
-
MASS_PROTON = 1.67262158e-27 # kg
|
38
|
-
MASS_NEUTRON = 1.67492716e-27 # kg
|
39
|
-
RYDBERG = 2.17987190389e-18 # kg m^2 / s^2
|
40
|
-
BOLTZMANN = 1.3806503e-23 # kg m^2 / K s^2
|
41
|
-
BOHR_MAGNETON = 9.27400899e-24 # A m^2
|
42
|
-
NUCLEAR_MAGNETON = 5.05078317e-27 # A m^2
|
43
|
-
ELECTRON_MAGNETIC_MOMENT = 9.28476362e-24 # A m^2
|
44
|
-
PROTON_MAGNETIC_MOMENT = 1.410606633e-26 # A m^2
|
45
|
-
MOLAR_GAS = 8.314472e0 # kg m^2 / K mol s^2
|
46
|
-
STANDARD_GAS_VOLUME = 2.2710981e-2 # m^3 / mol
|
47
|
-
MINUTE = 6e1 # s
|
48
|
-
HOUR = 3.6e3 # s
|
49
|
-
DAY = 8.64e4 # s
|
50
|
-
WEEK = 6.048e5 # s
|
51
|
-
INCH = 2.54e-2 # m
|
52
|
-
FOOT = 3.048e-1 # m
|
53
|
-
YARD = 9.144e-1 # m
|
54
|
-
MILE = 1.609344e3 # m
|
55
|
-
NAUTICAL_MILE = 1.852e3 # m
|
56
|
-
FATHOM = 1.8288e0 # m
|
57
|
-
MIL = 2.54e-5 # m
|
58
|
-
POINT = 3.52777777778e-4 # m
|
59
|
-
TEXPOINT = 3.51459803515e-4 # m
|
60
|
-
MICRON = 1e-6 # m
|
61
|
-
ANGSTROM = 1e-10 # m
|
62
|
-
HECTARE = 1e4 # m^2
|
63
|
-
ACRE = 4.04685642241e3 # m^2
|
64
|
-
BARN = 1e-28 # m^2
|
65
|
-
LITER = 1e-3 # m^3
|
66
|
-
US_GALLON = 3.78541178402e-3 # m^3
|
67
|
-
QUART = 9.46352946004e-4 # m^3
|
68
|
-
PINT = 4.73176473002e-4 # m^3
|
69
|
-
CUP = 2.36588236501e-4 # m^3
|
70
|
-
FLUID_OUNCE = 2.95735295626e-5 # m^3
|
71
|
-
TABLESPOON = 1.47867647813e-5 # m^3
|
72
|
-
TEASPOON = 4.92892159375e-6 # m^3
|
73
|
-
CANADIAN_GALLON = 4.54609e-3 # m^3
|
74
|
-
UK_GALLON = 4.546092e-3 # m^3
|
75
|
-
MILES_PER_HOUR = 4.4704e-1 # m / s
|
76
|
-
KILOMETERS_PER_HOUR = 2.77777777778e-1 # m / s
|
77
|
-
KNOT = 5.14444444444e-1 # m / s
|
78
|
-
POUND_MASS = 4.5359237e-1 # kg
|
79
|
-
OUNCE_MASS = 2.8349523125e-2 # kg
|
80
|
-
TON = 9.0718474e2 # kg
|
81
|
-
METRIC_TON = 1e3 # kg
|
82
|
-
UK_TON = 1.0160469088e3 # kg
|
83
|
-
TROY_OUNCE = 3.1103475e-2 # kg
|
84
|
-
CARAT = 2e-4 # kg
|
85
|
-
UNIFIED_ATOMIC_MASS = 1.66053873e-27 # kg
|
86
|
-
ATOMIC_MASS = 1.66053873e-27 # kg
|
87
|
-
GRAM_FORCE = 9.80665e-3 # kg m / s^2
|
88
|
-
POUND_FORCE = 4.44822161526e0 # kg m / s^2
|
89
|
-
KILOPOUND_FORCE = 4.44822161526e3 # kg m / s^2
|
90
|
-
POUNDAL = 1.38255e-1 # kg m / s^2
|
91
|
-
CALORIE = 4.1868e0 # kg m^2 / s^2
|
92
|
-
BTU = 1.05505585262e3 # kg m^2 / s^2
|
93
|
-
THERM = 1.05506e8 # kg m^2 / s^2
|
94
|
-
HORSEPOWER = 7.457e2 # kg m^2 / s^3
|
95
|
-
BAR = 1e5 # kg / m s^2
|
96
|
-
STD_ATMOSPHERE = 1.01325e5 # kg / m s^2
|
97
|
-
TORR = 1.33322368421e2 # kg / m s^2
|
98
|
-
METER_OF_MERCURY = 1.33322368421e5 # kg / m s^2
|
99
|
-
INCH_OF_MERCURY = 3.38638815789e3 # kg / m s^2
|
100
|
-
INCH_OF_WATER = 2.490889e2 # kg / m s^2
|
101
|
-
PSI = 6.89475729317e3 # kg / m s^2
|
102
|
-
POISE = 1e-1 # kg m^-1 s^-1
|
103
|
-
STOKES = 1e-4 # m^2 / s
|
104
|
-
FARADAY = 9.6485341472e4 # A s / mol
|
105
|
-
ELECTRON_CHARGE = 1.602176462e-19 # A s
|
106
|
-
GAUSS = 1e-4 # kg / A s^2
|
107
|
-
STILB = 1e4 # cd / m^2
|
108
|
-
LUMEN = 1e0 # cd sr
|
109
|
-
LUX = 1e0 # cd sr / m^2
|
110
|
-
PHOT = 1e4 # cd sr / m^2
|
111
|
-
FOOTCANDLE = 1.076e1 # cd sr / m^2
|
112
|
-
LAMBERT = 1e4 # cd sr / m^2
|
113
|
-
FOOTLAMBERT = 1.07639104e1 # cd sr / m^2
|
114
|
-
CURIE = 3.7e10 # 1 / s
|
115
|
-
ROENTGEN = 2.58e-4 # A s / kg
|
116
|
-
RAD = 1e-2 # m^2 / s^2
|
117
|
-
SOLAR_MASS = 1.98892e30 # kg
|
118
|
-
BOHR_RADIUS = 5.291772083e-11 # m
|
119
|
-
VACUUM_PERMITTIVITY = 8.854187817e-12 # A^2 s^4 / kg m^3
|
120
|
-
NEWTON = 1e0 # kg m / s^2
|
121
|
-
DYNE = 1e-5 # kg m / s^2
|
122
|
-
JOULE = 1e0 # kg m^2 / s^2
|
123
|
-
ERG = 1e-7 # kg m^2 / s^2
|
124
|
-
end
|
21
|
+
# Unitless constants in the MKS system (meters, kg, sec)
|
125
22
|
|
126
|
-
|
23
|
+
module MKS
|
24
|
+
SPEED_OF_LIGHT = 2.99792458e8 # m / s
|
25
|
+
GRAVITATIONAL_CONSTANT = 6.673e-11 # m^3 / kg s^2
|
26
|
+
PLANCKS_CONSTANT_H = 6.62606876e-34 # kg m^2 / s
|
27
|
+
PLANCKS_CONSTANT_HBAR = 1.05457159642e-34 # kg m^2 / s
|
28
|
+
VACUUM_PERMEABILITY = 1.25663706144e-6 # kg m / A^2 s^2
|
29
|
+
ASTRONOMICAL_UNIT = 1.49597870691e11 # m
|
30
|
+
LIGHT_YEAR = 9.46053620707e15 # m
|
31
|
+
PARSEC = 3.08567758135e16 # m
|
32
|
+
GRAV_ACCEL = 9.80665e0 # m / s^2
|
33
|
+
ELECTRON_VOLT = 1.602176462e-19 # kg m^2 / s^2
|
34
|
+
MASS_ELECTRON = 9.10938188e-31 # kg
|
35
|
+
MASS_MUON = 1.88353109e-28 # kg
|
36
|
+
MASS_PROTON = 1.67262158e-27 # kg
|
37
|
+
MASS_NEUTRON = 1.67492716e-27 # kg
|
38
|
+
RYDBERG = 2.17987190389e-18 # kg m^2 / s^2
|
39
|
+
BOLTZMANN = 1.3806503e-23 # kg m^2 / K s^2
|
40
|
+
BOHR_MAGNETON = 9.27400899e-24 # A m^2
|
41
|
+
NUCLEAR_MAGNETON = 5.05078317e-27 # A m^2
|
42
|
+
ELECTRON_MAGNETIC_MOMENT = 9.28476362e-24 # A m^2
|
43
|
+
PROTON_MAGNETIC_MOMENT = 1.410606633e-26 # A m^2
|
44
|
+
MOLAR_GAS = 8.314472e0 # kg m^2 / K mol s^2
|
45
|
+
STANDARD_GAS_VOLUME = 2.2710981e-2 # m^3 / mol
|
46
|
+
MINUTE = 6e1 # s
|
47
|
+
HOUR = 3.6e3 # s
|
48
|
+
DAY = 8.64e4 # s
|
49
|
+
WEEK = 6.048e5 # s
|
50
|
+
INCH = 2.54e-2 # m
|
51
|
+
FOOT = 3.048e-1 # m
|
52
|
+
YARD = 9.144e-1 # m
|
53
|
+
MILE = 1.609344e3 # m
|
54
|
+
NAUTICAL_MILE = 1.852e3 # m
|
55
|
+
FATHOM = 1.8288e0 # m
|
56
|
+
MIL = 2.54e-5 # m
|
57
|
+
POINT = 3.52777777778e-4 # m
|
58
|
+
TEXPOINT = 3.51459803515e-4 # m
|
59
|
+
MICRON = 1e-6 # m
|
60
|
+
ANGSTROM = 1e-10 # m
|
61
|
+
HECTARE = 1e4 # m^2
|
62
|
+
ACRE = 4.04685642241e3 # m^2
|
63
|
+
BARN = 1e-28 # m^2
|
64
|
+
LITER = 1e-3 # m^3
|
65
|
+
US_GALLON = 3.78541178402e-3 # m^3
|
66
|
+
QUART = 9.46352946004e-4 # m^3
|
67
|
+
PINT = 4.73176473002e-4 # m^3
|
68
|
+
CUP = 2.36588236501e-4 # m^3
|
69
|
+
FLUID_OUNCE = 2.95735295626e-5 # m^3
|
70
|
+
TABLESPOON = 1.47867647813e-5 # m^3
|
71
|
+
TEASPOON = 4.92892159375e-6 # m^3
|
72
|
+
CANADIAN_GALLON = 4.54609e-3 # m^3
|
73
|
+
UK_GALLON = 4.546092e-3 # m^3
|
74
|
+
MILES_PER_HOUR = 4.4704e-1 # m / s
|
75
|
+
KILOMETERS_PER_HOUR = 2.77777777778e-1 # m / s
|
76
|
+
KNOT = 5.14444444444e-1 # m / s
|
77
|
+
POUND_MASS = 4.5359237e-1 # kg
|
78
|
+
OUNCE_MASS = 2.8349523125e-2 # kg
|
79
|
+
TON = 9.0718474e2 # kg
|
80
|
+
METRIC_TON = 1e3 # kg
|
81
|
+
UK_TON = 1.0160469088e3 # kg
|
82
|
+
TROY_OUNCE = 3.1103475e-2 # kg
|
83
|
+
CARAT = 2e-4 # kg
|
84
|
+
UNIFIED_ATOMIC_MASS = 1.66053873e-27 # kg
|
85
|
+
ATOMIC_MASS = 1.66053873e-27 # kg
|
86
|
+
GRAM_FORCE = 9.80665e-3 # kg m / s^2
|
87
|
+
POUND_FORCE = 4.44822161526e0 # kg m / s^2
|
88
|
+
KILOPOUND_FORCE = 4.44822161526e3 # kg m / s^2
|
89
|
+
POUNDAL = 1.38255e-1 # kg m / s^2
|
90
|
+
CALORIE = 4.1868e0 # kg m^2 / s^2
|
91
|
+
BTU = 1.05505585262e3 # kg m^2 / s^2
|
92
|
+
THERM = 1.05506e8 # kg m^2 / s^2
|
93
|
+
HORSEPOWER = 7.457e2 # kg m^2 / s^3
|
94
|
+
BAR = 1e5 # kg / m s^2
|
95
|
+
STD_ATMOSPHERE = 1.01325e5 # kg / m s^2
|
96
|
+
TORR = 1.33322368421e2 # kg / m s^2
|
97
|
+
METER_OF_MERCURY = 1.33322368421e5 # kg / m s^2
|
98
|
+
INCH_OF_MERCURY = 3.38638815789e3 # kg / m s^2
|
99
|
+
INCH_OF_WATER = 2.490889e2 # kg / m s^2
|
100
|
+
PSI = 6.89475729317e3 # kg / m s^2
|
101
|
+
POISE = 1e-1 # kg m^-1 s^-1
|
102
|
+
STOKES = 1e-4 # m^2 / s
|
103
|
+
FARADAY = 9.6485341472e4 # A s / mol
|
104
|
+
ELECTRON_CHARGE = 1.602176462e-19 # A s
|
105
|
+
GAUSS = 1e-4 # kg / A s^2
|
106
|
+
STILB = 1e4 # cd / m^2
|
107
|
+
LUMEN = 1e0 # cd sr
|
108
|
+
LUX = 1e0 # cd sr / m^2
|
109
|
+
PHOT = 1e4 # cd sr / m^2
|
110
|
+
FOOTCANDLE = 1.076e1 # cd sr / m^2
|
111
|
+
LAMBERT = 1e4 # cd sr / m^2
|
112
|
+
FOOTLAMBERT = 1.07639104e1 # cd sr / m^2
|
113
|
+
CURIE = 3.7e10 # 1 / s
|
114
|
+
ROENTGEN = 2.58e-4 # A s / kg
|
115
|
+
RAD = 1e-2 # m^2 / s^2
|
116
|
+
SOLAR_MASS = 1.98892e30 # kg
|
117
|
+
BOHR_RADIUS = 5.291772083e-11 # m
|
118
|
+
VACUUM_PERMITTIVITY = 8.854187817e-12 # A^2 s^4 / kg m^3
|
119
|
+
NEWTON = 1e0 # kg m / s^2
|
120
|
+
DYNE = 1e-5 # kg m / s^2
|
121
|
+
JOULE = 1e0 # kg m^2 / s^2
|
122
|
+
ERG = 1e-7 # kg m^2 / s^2
|
123
|
+
end
|
127
124
|
|
128
125
|
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/stick/currency.rb
CHANGED
data/lib/stick/mapcar.rb
CHANGED
@@ -9,38 +9,50 @@
|
|
9
9
|
# NOTES:
|
10
10
|
#
|
11
11
|
# Google Summer of Code 2007 project for Ruby Central Inc.
|
12
|
+
#
|
13
|
+
# TODO:
|
14
|
+
# - #mapcar should ne be defined in toplevel. But Matrix
|
15
|
+
# is using it at class-level. WTF?
|
12
16
|
|
13
17
|
require 'generator'
|
14
|
-
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
|
19
|
+
#module Enumerable
|
20
|
+
|
21
|
+
# Non-recursive mapcar (works on all Enumerables)
|
22
|
+
|
23
|
+
def mapcar(*enums)
|
24
|
+
generators = enums.collect { |e| Generator.new(e) }
|
25
|
+
result = []
|
26
|
+
while true
|
27
|
+
begin
|
28
|
+
params = generators.collect { |g| g.current; g.next }
|
29
|
+
rescue EOFError
|
30
|
+
return result
|
31
|
+
end
|
32
|
+
result << yield(*params)
|
25
33
|
end
|
26
|
-
result << yield(*params)
|
27
34
|
end
|
28
|
-
end
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
#
|
37
|
+
|
38
|
+
def map(*enums)
|
39
|
+
generators = []; enums.each { |e| generators << Generator.new(e) }
|
40
|
+
while true
|
41
|
+
begin
|
42
|
+
params = []; generators.each { |g| g.current; params << g.next }
|
43
|
+
rescue EOFError
|
44
|
+
return
|
45
|
+
end
|
46
|
+
yield(*params)
|
37
47
|
end
|
38
|
-
yield(*params)
|
39
48
|
end
|
40
|
-
|
49
|
+
|
50
|
+
#end
|
51
|
+
|
41
52
|
|
42
53
|
class Array
|
43
|
-
|
54
|
+
|
55
|
+
def self.map(n, *arrays)
|
44
56
|
len = arrays.length
|
45
57
|
if n == 0
|
46
58
|
n = arrays[0].length
|
@@ -57,5 +69,6 @@ class Array
|
|
57
69
|
yield(*params)
|
58
70
|
end
|
59
71
|
end
|
72
|
+
|
60
73
|
end
|
61
74
|
|
data/lib/stick/matrix.rb
CHANGED
@@ -1,22 +1,18 @@
|
|
1
|
-
# = TITLE:
|
2
|
-
#
|
3
|
-
# Matrix Extensions
|
4
|
-
#
|
5
|
-
# AUTHOR:
|
6
|
-
#
|
7
|
-
# Cosmin Bonchis
|
8
|
-
#
|
9
|
-
# NOTES:
|
10
|
-
#
|
11
|
-
# Google Summer of Code 2007 project for Ruby Central Inc.
|
12
|
-
|
13
1
|
require 'rational'
|
14
|
-
require 'matrix'
|
15
2
|
|
16
3
|
require 'stick/mapcar'
|
4
|
+
require 'stick/matrix/core'
|
5
|
+
require 'stick/matrix/givens'
|
6
|
+
require 'stick/matrix/hessenberg'
|
7
|
+
require 'stick/matrix/householder'
|
8
|
+
require 'stick/matrix/jacobi'
|
9
|
+
require 'stick/matrix/lu'
|
10
|
+
|
17
11
|
|
12
|
+
module Stick
|
18
13
|
|
19
14
|
class Vector
|
15
|
+
|
20
16
|
include Enumerable
|
21
17
|
|
22
18
|
module Norm
|
@@ -599,168 +595,6 @@ class Matrix
|
|
599
595
|
end
|
600
596
|
end
|
601
597
|
|
602
|
-
module LU
|
603
|
-
#
|
604
|
-
# Return the Gauss vector, MC, Golub, 3.2.1 Gauss Transformation, p94
|
605
|
-
#
|
606
|
-
def LU.gauss_vector(mat, k)
|
607
|
-
t = mat.column2matrix(k)
|
608
|
-
tk = t[k, 0]
|
609
|
-
(0..k).each{|i| t[i, 0] = 0}
|
610
|
-
return t if tk == 0
|
611
|
-
(k+1...mat.row_size).each{|i| t[i, 0] = t[i, 0].to_f / tk}
|
612
|
-
t
|
613
|
-
end
|
614
|
-
|
615
|
-
#
|
616
|
-
# Return the Gauss transformation matrix: M_k = I - tau * e_k^T
|
617
|
-
#
|
618
|
-
def LU.gauss(mat, k)
|
619
|
-
i = Matrix.I(mat.column_size)
|
620
|
-
tau = gauss_vector(mat, k)
|
621
|
-
e = i.row2matrix(k)
|
622
|
-
i - tau * e
|
623
|
-
end
|
624
|
-
|
625
|
-
#
|
626
|
-
# LU factorization: A = LU
|
627
|
-
# where L is lower triangular and U is upper triangular
|
628
|
-
#
|
629
|
-
def LU.factorization(mat)
|
630
|
-
u = mat.clone
|
631
|
-
n = u.column_size
|
632
|
-
i = Matrix.I(n)
|
633
|
-
l = i.clone
|
634
|
-
(n-1).times {|k|
|
635
|
-
mk = gauss(u, k)
|
636
|
-
u = mk * u # M_{n-1} * ... * M_1 * A = U
|
637
|
-
l += i - mk # L = M_1^{-1} * ... * M_{n-1}^{-1} = I + sum_{k=1}^{n-1} tau * e
|
638
|
-
}
|
639
|
-
return l, u
|
640
|
-
end
|
641
|
-
end
|
642
|
-
|
643
|
-
#
|
644
|
-
# Return the upper triangular matrix of LU factorization
|
645
|
-
# M_{n-1} * ... * M_1 * A = U
|
646
|
-
#
|
647
|
-
def U
|
648
|
-
LU.factorization(self)[1]
|
649
|
-
end
|
650
|
-
|
651
|
-
#
|
652
|
-
# Return the lower triangular matrix of LU factorization
|
653
|
-
# L = M_1^{-1} * ... * M_{n-1}^{-1} = I + sum_{k=1}^{n-1} tau * e
|
654
|
-
#
|
655
|
-
def L
|
656
|
-
LU.factorization(self)[0]
|
657
|
-
end
|
658
|
-
|
659
|
-
module Householder
|
660
|
-
#
|
661
|
-
# a QR factorization that uses Householder transformation
|
662
|
-
# Q^T * A = R
|
663
|
-
# MC, Golub & van Loan, pg 224, 5.2.1 Householder QR
|
664
|
-
#
|
665
|
-
def Householder.QR(mat)
|
666
|
-
h = []
|
667
|
-
a = mat.clone
|
668
|
-
m = a.row_size
|
669
|
-
n = a.column_size
|
670
|
-
n.times{|j|
|
671
|
-
v, beta = a[j..m - 1, j].house
|
672
|
-
|
673
|
-
h[j] = Matrix.diag(Matrix.I(j), Matrix.I(m-j)- beta * (v * v.t))
|
674
|
-
|
675
|
-
a[j..m-1, j..n-1] = (Matrix.I(m-j) - beta * (v * v.t)) * a[j..m-1, j..n-1]
|
676
|
-
a[(j+1)..m-1,j] = v[2..(m-j)] if j < m - 1 }
|
677
|
-
h
|
678
|
-
end
|
679
|
-
|
680
|
-
#
|
681
|
-
# From the essential part of Householder vector
|
682
|
-
# it returns the coresponding upper(U_j)/lower(V_j) matrix
|
683
|
-
#
|
684
|
-
def Householder.bidiagUV(essential, dim, beta)
|
685
|
-
v = Vector.concat(Vector[1], essential)
|
686
|
-
dimv = v.size
|
687
|
-
Matrix.diag(Matrix.I(dim - dimv), Matrix.I(dimv) - beta * (v * v.t) )
|
688
|
-
end
|
689
|
-
|
690
|
-
#
|
691
|
-
# Householder Bidiagonalization algorithm. MC, Golub, pg 252, Algorithm 5.4.2
|
692
|
-
# Returns the matrices U_B and V_B such that: U_B^T * A * V_B = B,
|
693
|
-
# where B is upper bidiagonal.
|
694
|
-
#
|
695
|
-
def Householder.bidiag(mat)
|
696
|
-
a = mat.clone
|
697
|
-
m = a.row_size
|
698
|
-
n = a.column_size
|
699
|
-
ub = Matrix.I(m)
|
700
|
-
vb = Matrix.I(n)
|
701
|
-
n.times{|j|
|
702
|
-
v, beta = a[j..m-1,j].house
|
703
|
-
a[j..m-1, j..n-1] = (Matrix.I(m-j) - beta * (v * v.t)) * a[j..m-1, j..n-1]
|
704
|
-
a[j+1..m-1, j] = v[1..(m-j-1)]
|
705
|
-
ub *= bidiagUV(a[j+1..m-1,j], m, beta) #Ub = U_1 * U_2 * ... * U_n
|
706
|
-
if j < n - 2
|
707
|
-
v, beta = (a[j, j+1..n-1]).house
|
708
|
-
a[j..m-1, j+1..n-1] = a[j..m-1, j+1..n-1] * (Matrix.I(n-j-1) - beta * (v * v.t))
|
709
|
-
a[j, j+2..n-1] = v[1..n-j-2]
|
710
|
-
vb *= bidiagUV(a[j, j+2..n-1], n, beta) #Vb = V_1 * U_2 * ... * V_n-2
|
711
|
-
end }
|
712
|
-
return ub, vb
|
713
|
-
end
|
714
|
-
|
715
|
-
#
|
716
|
-
#Householder Reduction to Hessenberg Form
|
717
|
-
#
|
718
|
-
def Householder.toHessenberg(mat)
|
719
|
-
h = mat.clone
|
720
|
-
n = h.row_size
|
721
|
-
u0 = Matrix.I(n)
|
722
|
-
for k in (0...n - 2)
|
723
|
-
v, beta = h[k+1..n-1, k].house #the householder matrice part
|
724
|
-
houseV = Matrix.I(n-k-1) - beta * (v * v.t)
|
725
|
-
u0 *= Matrix.diag(Matrix.I(k+1), houseV)
|
726
|
-
h[k+1..n-1, k..n-1] = houseV * h[k+1..n-1, k..n-1]
|
727
|
-
h[0..n-1, k+1..n-1] = h[0..n-1, k+1..n-1] * houseV
|
728
|
-
end
|
729
|
-
return h, u0
|
730
|
-
end
|
731
|
-
|
732
|
-
|
733
|
-
end #end of Householder module
|
734
|
-
|
735
|
-
#
|
736
|
-
# Returns the upper bidiagonal matrix obtained with Householder Bidiagonalization algorithm
|
737
|
-
#
|
738
|
-
def bidiagonal
|
739
|
-
ub, vb = Householder.bidiag(self)
|
740
|
-
ub.t * self * vb
|
741
|
-
end
|
742
|
-
|
743
|
-
#
|
744
|
-
# Returns the orthogonal matrix Q of Householder QR factorization
|
745
|
-
# where Q = H_1 * H_2 * H_3 * ... * H_n,
|
746
|
-
#
|
747
|
-
def houseQ
|
748
|
-
h = Householder.QR(self)
|
749
|
-
q = h[0]
|
750
|
-
(1...h.size).each{|i| q *= h[i]}
|
751
|
-
q
|
752
|
-
end
|
753
|
-
|
754
|
-
#
|
755
|
-
# Returns the matrix R of Householder QR factorization
|
756
|
-
# R = H_n * H_n-1 * ... * H_1 * A is an upper triangular matrix
|
757
|
-
#
|
758
|
-
def houseR
|
759
|
-
h = Householder.QR(self)
|
760
|
-
r = self.clone
|
761
|
-
h.size.times{|i| r = h[i] * r}
|
762
|
-
r
|
763
|
-
end
|
764
598
|
|
765
599
|
#
|
766
600
|
# Modified Gram Schmidt QR factorization (MC, Golub, p. 232)
|
@@ -798,225 +632,6 @@ class Matrix
|
|
798
632
|
gram_schmidt[1]
|
799
633
|
end
|
800
634
|
|
801
|
-
|
802
|
-
module Givens
|
803
|
-
#
|
804
|
-
# Returns the values "c and s" of a Given rotation
|
805
|
-
# MC, Golub, pg 216, Alghorithm 5.1.3
|
806
|
-
#
|
807
|
-
def Givens.givens(a, b)
|
808
|
-
if b == 0
|
809
|
-
c = 0; s = 0
|
810
|
-
else
|
811
|
-
if b.abs > a.abs
|
812
|
-
tau = Float(-a)/b; s = 1/Math.sqrt(1+tau**2); c = s * tau
|
813
|
-
else
|
814
|
-
tau = Float(-b)/a; c = 1/Math.sqrt(1+tau**2); s = c * tau
|
815
|
-
end
|
816
|
-
end
|
817
|
-
return c, s
|
818
|
-
end
|
819
|
-
|
820
|
-
#
|
821
|
-
# a QR factorization using Givens rotation
|
822
|
-
# Computes the upper triangular matrix R and the orthogonal matrix Q
|
823
|
-
# where Q^t A = R (MC, Golub, p227 algorithm 5.2.2)
|
824
|
-
#
|
825
|
-
def Givens.QR(mat)
|
826
|
-
r = mat.clone
|
827
|
-
m = r.row_size
|
828
|
-
n = r.column_size
|
829
|
-
q = Matrix.I(m)
|
830
|
-
n.times{|j|
|
831
|
-
m-1.downto(j+1){|i|
|
832
|
-
c, s = givens(r[i - 1, j], r[i, j])
|
833
|
-
qt = Matrix.I(m); qt[i-1..i, i-1..i] = Matrix[[c, s],[-s, c]]
|
834
|
-
q *= qt
|
835
|
-
r[i-1..i, j..n-1] = Matrix[[c, -s],[s, c]] * r[i-1..i, j..n-1]}}
|
836
|
-
return r, q
|
837
|
-
end
|
838
|
-
|
839
|
-
end
|
840
|
-
|
841
|
-
#
|
842
|
-
# Returns the upper triunghiular matrix R of a Givens QR factorization
|
843
|
-
#
|
844
|
-
def givensR
|
845
|
-
Givens.QR(self)[0]
|
846
|
-
end
|
847
|
-
|
848
|
-
#
|
849
|
-
# Returns the orthogonal matrix Q of Givens QR factorization.
|
850
|
-
# Q = G_1 * ... * G_t where G_j is the j'th Givens rotation
|
851
|
-
# and 't' is the total number of rotations
|
852
|
-
#
|
853
|
-
def givensQ
|
854
|
-
Givens.QR(self)[1]
|
855
|
-
end
|
856
|
-
|
857
|
-
module Hessenberg
|
858
|
-
#
|
859
|
-
# the matrix must be an upper R^(n x n) Hessenberg matrix
|
860
|
-
#
|
861
|
-
def Hessenberg.QR(mat)
|
862
|
-
r = mat.clone
|
863
|
-
n = r.row_size
|
864
|
-
q = Matrix.I(n)
|
865
|
-
for j in (0...n-1)
|
866
|
-
c, s = Givens.givens(r[j,j], r[j+1, j])
|
867
|
-
cs = Matrix[[c, s], [-s, c]]
|
868
|
-
q *= Matrix.diag(Matrix.I(j), cs, Matrix.I(n - j - 2))
|
869
|
-
r[j..j+1, j..n-1] = cs.t * r[j..j+1, j..n-1]
|
870
|
-
end
|
871
|
-
return q, r
|
872
|
-
end
|
873
|
-
end
|
874
|
-
|
875
|
-
#
|
876
|
-
# Returns the orthogonal matrix Q of Hessenberg QR factorization
|
877
|
-
# Q = G_1 *...* G_(n-1) where G_j is the Givens rotation G_j = G(j, j+1, omega_j)
|
878
|
-
#
|
879
|
-
def hessenbergQ
|
880
|
-
Hessenberg.QR(self)[0]
|
881
|
-
end
|
882
|
-
|
883
|
-
#
|
884
|
-
# Returns the upper triunghiular matrix R of a Hessenberg QR factorization
|
885
|
-
#
|
886
|
-
def hessenbergR
|
887
|
-
Hessenberg.QR(self)[1]
|
888
|
-
end
|
889
|
-
|
890
|
-
#
|
891
|
-
# Return an upper Hessenberg matrix obtained with Householder reduction to Hessenberg Form algorithm
|
892
|
-
#
|
893
|
-
def hessenberg_form_H
|
894
|
-
Householder.toHessenberg(self)[0]
|
895
|
-
end
|
896
|
-
|
897
|
-
#
|
898
|
-
# The real Schur decomposition.
|
899
|
-
# The eigenvalues are aproximated in diagonal elements of the real Schur decomposition matrix
|
900
|
-
#
|
901
|
-
def realSchur(eps = 1.0e-10, steps = 100)
|
902
|
-
h = self.hessenberg_form_H
|
903
|
-
h1 = Matrix[]
|
904
|
-
i = 0
|
905
|
-
loop do
|
906
|
-
h1 = h.hessenbergR * h.hessenbergQ
|
907
|
-
break if Matrix.diag_in_delta?(h1, h, eps) or steps <= 0
|
908
|
-
h = h1.clone
|
909
|
-
steps -= 1
|
910
|
-
i += 1
|
911
|
-
end
|
912
|
-
h1
|
913
|
-
end
|
914
|
-
|
915
|
-
|
916
|
-
module Jacobi
|
917
|
-
#
|
918
|
-
# Returns the nurm of the off-diagonal element
|
919
|
-
#
|
920
|
-
def Jacobi.off(a)
|
921
|
-
n = a.row_size
|
922
|
-
sum = 0
|
923
|
-
n.times{|i| n.times{|j| sum += a[i, j]**2 if j != i}}
|
924
|
-
Math.sqrt(sum)
|
925
|
-
end
|
926
|
-
|
927
|
-
#
|
928
|
-
# Returns the index pair (p, q) with 1<= p < q <= n and A[p, q] is the maximum in absolute value
|
929
|
-
#
|
930
|
-
def Jacobi.max(a)
|
931
|
-
n = a.row_size
|
932
|
-
max = 0
|
933
|
-
p = 0
|
934
|
-
q = 0
|
935
|
-
n.times{|i|
|
936
|
-
((i+1)...n).each{|j|
|
937
|
-
val = a[i, j].abs
|
938
|
-
if val > max
|
939
|
-
max = val
|
940
|
-
p = i
|
941
|
-
q = j
|
942
|
-
end }}
|
943
|
-
return p, q
|
944
|
-
end
|
945
|
-
|
946
|
-
#
|
947
|
-
# Compute the cosine-sine pair (c, s) for the element A[p, q]
|
948
|
-
#
|
949
|
-
def Jacobi.sym_schur2(a, p, q)
|
950
|
-
if a[p, q] != 0
|
951
|
-
tau = Float(a[q, q] - a[p, p])/(2 * a[p, q])
|
952
|
-
if tau >= 0
|
953
|
-
t = 1./(tau + Math.sqrt(1 + tau ** 2))
|
954
|
-
else
|
955
|
-
t = -1./(-tau + Math.sqrt(1 + tau ** 2))
|
956
|
-
end
|
957
|
-
c = 1./Math.sqrt(1 + t ** 2)
|
958
|
-
s = t * c
|
959
|
-
else
|
960
|
-
c = 1
|
961
|
-
s = 0
|
962
|
-
end
|
963
|
-
return c, s
|
964
|
-
end
|
965
|
-
|
966
|
-
#
|
967
|
-
# Returns the Jacobi rotation matrix
|
968
|
-
#
|
969
|
-
def Jacobi.J(p, q, c, s, n)
|
970
|
-
j = Matrix.I(n)
|
971
|
-
j[p,p] = c; j[p, q] = s
|
972
|
-
j[q,p] = -s; j[q, q] = c
|
973
|
-
j
|
974
|
-
end
|
975
|
-
end
|
976
|
-
|
977
|
-
#
|
978
|
-
# Classical Jacobi 8.4.3 Golub & van Loan
|
979
|
-
#
|
980
|
-
def cJacobi(tol = 1.0e-10)
|
981
|
-
a = self.clone
|
982
|
-
n = row_size
|
983
|
-
v = Matrix.I(n)
|
984
|
-
eps = tol * a.normF
|
985
|
-
while Jacobi.off(a) > eps
|
986
|
-
p, q = Jacobi.max(a)
|
987
|
-
c, s = Jacobi.sym_schur2(a, p, q)
|
988
|
-
#print "\np:#{p} q:#{q} c:#{c} s:#{s}\n"
|
989
|
-
j = Jacobi.J(p, q, c, s, n)
|
990
|
-
a = j.t * a * j
|
991
|
-
v = v * j
|
992
|
-
end
|
993
|
-
return a, v
|
994
|
-
end
|
995
|
-
|
996
|
-
#
|
997
|
-
# Returns the aproximation matrix computed with Classical Jacobi algorithm.
|
998
|
-
# The aproximate eigenvalues values are in the diagonal of the matrix A.
|
999
|
-
#
|
1000
|
-
def cJacobiA(tol = 1.0e-10)
|
1001
|
-
cJacobi(tol)[0]
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
#
|
1005
|
-
# Returns a Vector with the eigenvalues aproximated values.
|
1006
|
-
# The eigenvalues are computed with the Classic Jacobi Algorithm.
|
1007
|
-
#
|
1008
|
-
def eigenvaluesJacobi
|
1009
|
-
a = cJacobiA
|
1010
|
-
Vector[*(0...row_size).collect{|i| a[i, i]}]
|
1011
|
-
end
|
1012
|
-
|
1013
|
-
#
|
1014
|
-
# Returns the orthogonal matrix obtained with the Jacobi eigenvalue algorithm.
|
1015
|
-
# The columns of V are the eigenvector.
|
1016
|
-
#
|
1017
|
-
def cJacobiV(tol = 1.0e-10)
|
1018
|
-
cJacobi(tol)[1]
|
1019
|
-
end
|
1020
635
|
end
|
1021
636
|
|
1022
|
-
|
637
|
+
end
|