matrix_extensions 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88ac601a61d4ccb18628977f97571ed3855545b1
4
+ data.tar.gz: 2c6efe2d7d213daebe2890c8ed1f86340703244d
5
+ SHA512:
6
+ metadata.gz: 24ff51ffd991091061e34dc8786de49c360fe38208760e5d2f85d5589b95eb3590584f85235086b7a8174665338999078f6529afdd3ba2488ff07efdadf84746
7
+ data.tar.gz: 86e2592e5c1ceb6bea3f823d05af766614de133cc6dc04c3b708c557977f3bfc464f68d5d116968e6a0a0f6cc9896118ea0dfa7e3b2ce1961a6398b028fc3fa8
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .ruby-gemset
24
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in matrix_extensions.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Michael Imstepf
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Extension of the Ruby Matrix class
2
+
3
+ This gem extends the [Ruby Matrix class](http://www.ruby-doc.org/stdlib-2.1.2/libdoc/matrix/rdoc/Matrix.html) by providing additional methods.
4
+
5
+ It is more light-weight and less powerful than the [SciRuby NMatrix module](https://github.com/SciRuby/nmatrix). It is also easier to install than the NMatrix module since there is no need to manually install libraries and configure the operating system.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'matrix_extensions'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install matrix_extensions
20
+
21
+ ## Usage
22
+
23
+ Element-wise multiplication:
24
+
25
+ ```ruby
26
+ require 'matrix_extensions' # if not loaded automatically
27
+
28
+ MatrixExtended[ [1,2,3], [4,5,6] ].element_multiplication MatrixExtended[ [2,3,4], [5,6,7] ]
29
+ => MatrixExtended[[2, 6, 12], [20, 30, 42]]
30
+ ```
31
+
32
+ Element-wise division:
33
+
34
+ ```ruby
35
+ require 'matrix_extensions' # if not loaded automatically
36
+
37
+ MatrixExtended[ [2,4,6], [2.0,10,20] ].element_division MatrixExtended[ [2,2,6], [4,5,10] ]
38
+ => MatrixExtended[[1, 2, 1], [0.5, 2, 2]]
39
+ ```
40
+
41
+ Element-wise exponentiation:
42
+
43
+ ```ruby
44
+ require 'matrix_extensions' # if not loaded automatically
45
+
46
+ MatrixExtended[ [2,4], [1,4] ].element_exponentiation MatrixExtended[ [2,4], [1,4]] ]
47
+ => MatrixExtended[[4, 256], [1, 256]]
48
+ ```
49
+
50
+ Prefilled matrix with zeros or ones:
51
+
52
+ ```ruby
53
+ require 'matrix_extensions' # if not loaded automatically
54
+
55
+ MatrixExtended.zeros(2,4)
56
+ => MatrixExtended[[0, 0, 0, 0], [0, 0, 0, 0]]
57
+
58
+ MatrixExtended.ones(2,2)
59
+ => MatrixExtended[[1, 1], [1, 1]]
60
+ ```
61
+
62
+ Concatenating matrices and vectors horizontally:
63
+
64
+ This iterates through a list of matrices and vectors and appends columns of each list one after another. The row number of all matrices and vectors must be equal. The number of arguments passed in can be freely chosen.
65
+
66
+ ```ruby
67
+ require 'matrix_extensions' # if not loaded automatically
68
+
69
+ m1 = Matrix[ [1,2,3], [4,5,6] ]
70
+ m2 = Matrix[ [2,3,4], [5,6,7] ]
71
+ v = Vector[ 3,4 ]
72
+
73
+ MatrixExtended.hconcat(m1, m2, v)
74
+ => MatrixExtended[[1, 2, 3, 2, 3, 4, 3], [4, 5, 6, 5, 6, 7, 4]]
75
+ ```
76
+
77
+ Concatenating matrices and vectors vertically:
78
+
79
+ This iterates through a list of matrices and vectors and appends rows of each list one after another. The column number of all matrices and vectors must be equal. The number of arguments passed in can be freely chosen.
80
+
81
+ ```ruby
82
+ require 'matrix_extensions' # if not loaded automatically
83
+
84
+ m1 = Matrix[ [1,2,3], [4,5,6] ]
85
+ m2 = Matrix[ [2,3,4], [5,6,7] ]
86
+ v = Vector[ 3,4,5 ]
87
+
88
+ MatrixExtended.vconcat(m1, m2, v)
89
+ => MatrixExtended[[1, 2, 3], [4, 5, 6], [2, 3, 4], [5, 6, 7], [3, 4, 5]]
90
+ ```
91
+
92
+ ## Contributing
93
+
94
+ 1. Fork it ( https://github.com/[my-github-username]/matrix_extensions/fork )
95
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
96
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
97
+ 4. Push to the branch (`git push origin my-new-feature`)
98
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,201 @@
1
+ require "matrix_extensions/version"
2
+ require 'matrix'
3
+
4
+ # An extension to the Ruby Matrix class.
5
+ # @author Michael Imstepf
6
+ class MatrixExtended < Matrix
7
+ # Converts a Matrix to an MatrixExtended.
8
+ # @param m [Matrix] matrix
9
+ # @return [MatrixExtended] matrix
10
+ # @raise [TypeError] if matrices are not of type Matrix
11
+ def self.convert_to_matrix_extended(m)
12
+ raise TypeError, "#{m.class} is not a Matrix" unless m.is_a?(Matrix)
13
+
14
+ self.columns(m.column_vectors)
15
+ end
16
+
17
+ # Matrix prefilled with zeros.
18
+ # @param m [MatrixExtended] matrix
19
+ # @return [MatrixExtended] matrix
20
+ def self.zeros(rows = 1, columns = 1)
21
+ MatrixExtended.build(rows, columns) { 0 }
22
+ end
23
+ self.singleton_class.send(:alias_method, :zeroes, :zeros)
24
+
25
+ # Matrix prefilled with ones.
26
+ # @param m [MatrixExtended] matrix
27
+ # @return [MatrixExtended] matrix
28
+ def self.ones(rows = 1, columns = 1)
29
+ MatrixExtended.build(rows, columns) { 1 }
30
+ end
31
+
32
+ # Concatenates two matrices horizontally (resulting in more columns).
33
+ # @param *matrices [MatrixExtended] matrices
34
+ # @return [MatrixExtended] concatenated matrix
35
+ # @raise [ErrDimensionMismatch] if dimensions don't match
36
+ # @raise [TypeError] if matrices are not of type Matrix or Vector
37
+ def self.hconcat(*matrices)
38
+ columns = []
39
+ matrices.each do |m|
40
+ raise TypeError, "#{m.class} is not a Matrix or Vector" unless m.is_a?(Matrix) || m.is_a?(Vector)
41
+
42
+ # convert Vector to Matrix
43
+ m = self.convert_vector_to_matrix(m, :column) if m.is_a? Vector
44
+
45
+ # check if dimensions match
46
+ row_count ||= m.row_count
47
+ Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count
48
+
49
+ # prepare array of columns
50
+ m.column_vectors.each do |v|
51
+ columns << v.to_a
52
+ end
53
+ end
54
+
55
+ # create new matrix
56
+ self.columns(columns)
57
+ end
58
+
59
+ # Concatenates two matrices vertically (resulting in more rows).
60
+ # @param *matrices [MatrixExtended] matrices
61
+ # @return [MatrixExtended] concatenated matrix
62
+ # @raise [ErrDimensionMismatch] if dimensions don't match
63
+ # @raise [TypeError] if matrices are not of type Matrix or Vector
64
+ def self.vconcat(*matrices)
65
+ rows = []
66
+ matrices.each do |m|
67
+ raise TypeError, "#{m.class} is not a Matrix or Vector" unless m.is_a?(Matrix) || m.is_a?(Vector)
68
+
69
+ # convert Vector to Matrix
70
+ m = self.convert_vector_to_matrix(m, :row) if m.is_a? Vector
71
+
72
+ # check if dimensions match
73
+ column_count ||= m.column_count
74
+ Matrix.Raise ErrDimensionMismatch unless column_count == m.column_count
75
+
76
+ # prepare array of columns
77
+ m.row_vectors.each do |v|
78
+ rows << v.to_a
79
+ end
80
+ end
81
+
82
+ # create new matrix
83
+ self.rows(rows)
84
+ end
85
+
86
+ # Element-wise division.
87
+ # @param m [MatrixExtended] matrix
88
+ # @return [MatrixExtended] matrix
89
+ # @raise [ErrDimensionMismatch] if dimensions don't match
90
+ def element_division(m)
91
+ case m
92
+ when Numeric
93
+ return self./ m
94
+ when Vector
95
+ if row_count > column_count
96
+ # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch)
97
+ m = self.class.convert_vector_to_matrix(m, :column)
98
+ else
99
+ # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch)
100
+ m = self.class.convert_vector_to_matrix(m, :row)
101
+ end
102
+ when Matrix
103
+ else
104
+ return apply_through_coercion(m, __method__)
105
+ end
106
+
107
+ Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
108
+
109
+ rows = Array.new(row_count) do |i|
110
+ Array.new(column_count) do|j|
111
+ self[i, j] / m[i, j]
112
+ end
113
+ end
114
+ new_matrix rows, column_count
115
+ end
116
+
117
+ # Element-wise multiplication.
118
+ # @param m [MatrixExtended] matrix
119
+ # @return [MatrixExtended] matrix
120
+ # @raise [ErrDimensionMismatch] if dimensions don't match
121
+ def element_multiplication(m)
122
+ case m
123
+ when Numeric
124
+ return self.* m
125
+ when Vector
126
+ if row_count > column_count
127
+ # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch)
128
+ m = self.class.convert_vector_to_matrix(m, :column)
129
+ else
130
+ # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch)
131
+ m = self.class.convert_vector_to_matrix(m, :row)
132
+ end
133
+ when Matrix
134
+ else
135
+ return apply_through_coercion(m, __method__)
136
+ end
137
+
138
+ Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
139
+
140
+ rows = Array.new(row_count) do |i|
141
+ Array.new(column_count) do|j|
142
+ self[i, j] * m[i, j]
143
+ end
144
+ end
145
+ new_matrix rows, column_count
146
+ end
147
+
148
+ # Element-wise exponentiation.
149
+ # @param m [MatrixExtended] matrix
150
+ # @return [MatrixExtended] matrix
151
+ # @raise [ErrDimensionMismatch] if dimensions don't match
152
+ def element_exponentiation(m)
153
+ case m
154
+ when Numeric
155
+ # self.** m will break
156
+ rows = @rows.collect {|row|
157
+ row.collect {|e| e ** m }
158
+ }
159
+ return new_matrix rows, column_count
160
+ when Vector
161
+ if row_count > column_count
162
+ # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch)
163
+ m = self.class.convert_vector_to_matrix(m, :column)
164
+ else
165
+ # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch)
166
+ m = self.class.convert_vector_to_matrix(m, :row)
167
+ end
168
+ when Matrix
169
+ else
170
+ return apply_through_coercion(m, __method__)
171
+ end
172
+
173
+ Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
174
+
175
+ rows = Array.new(row_count) do |i|
176
+ Array.new(column_count) do|j|
177
+ self[i, j] ** m[i, j]
178
+ end
179
+ end
180
+ new_matrix rows, column_count
181
+ end
182
+
183
+ private
184
+
185
+ # Convert vector to matrix for arithmetic operations.
186
+ # @param vector [Vector] vector
187
+ # @param dimension [Symbol] :row or :column
188
+ # @return [MatrixExtended] matrix
189
+ # @raise [TypeError] if vector ist not of type Vector
190
+ def self.convert_vector_to_matrix(v, dimension)
191
+ raise TypeError, "#{v.class} is not a Vector" unless v.is_a? Vector
192
+
193
+ if dimension == :row
194
+ self.row_vector(v)
195
+ elsif dimension == :column
196
+ self.column_vector(v)
197
+ else
198
+ raise ArgumentError
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,3 @@
1
+ module MatrixExtensions
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'matrix_extensions/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "matrix_extensions"
8
+ spec.version = MatrixExtensions::VERSION
9
+ spec.authors = ["Michael Imstepf"]
10
+ spec.email = ["michael.imstepf@gmail.com"]
11
+ spec.summary = %q{Extension of the Ruby Matrix class.}
12
+ spec.description = %q{Element-wise matrix operations, concatenation and pre-filled matrices with single values.}
13
+ spec.homepage = "https://github.com/michaelimstepf/matrix-extensions"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: matrix_extensions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Imstepf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Element-wise matrix operations, concatenation and pre-filled matrices
56
+ with single values.
57
+ email:
58
+ - michael.imstepf@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - lib/matrix_extensions.rb
69
+ - lib/matrix_extensions/version.rb
70
+ - matrix_extensions.gemspec
71
+ homepage: https://github.com/michaelimstepf/matrix-extensions
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.2.2
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Extension of the Ruby Matrix class.
95
+ test_files: []