Class: Algebra::MatrixAlgebra

Inherits:
Object
  • Object
show all
Extended by:
AlgebraCreator
Includes:
AlgebraBase, ElementaryDivisor, GaussianElimination, Orthogonalization, Enumerable
Defined in:
lib/algebra/jordan-form.rb,
lib/algebra/linear-algebra.rb,
lib/algebra/matrix-algebra.rb,
lib/algebra/elementary-divisor.rb,
lib/algebra/elementary-divisor.rb,
lib/algebra/gaussian-elimination.rb,
lib/algebra/matrix-algebra-triplet.rb

Direct Known Subclasses

Covector, SquareMatrix, Vector

Constant Summary collapse

Matrices =

require ‘algebra/linear-algebra’ require ‘algebra/matrix-algebra-triplet’ require ‘algebra/elementary-divisor’ require ‘algebra/jordan-form’

{}

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AlgebraCreator

create, superior?, sysvar, wedge

Methods included from GaussianElimination

#divide_c, #divide_c!, #divide_r, #divide_r!, #kernel_basis, #left_eliminate!, #left_eliminate_euclidian!, #left_inverse, #left_sweep, #mix_c, #mix_c!, #mix_r, #mix_r!, #multiply_c, #multiply_c!, #multiply_r, #multiply_r!, #sswap_r!, #step_matrix?, #swap_c, #swap_c!, #swap_r, #swap_r!

Methods included from ElementaryDivisor

#_coeff, #e_diagonalize, #e_diagonalize!, #e_inverse, #el_sweep!, #el_sweep_old!, #elementary_divisor, factorize, #horizontal_sweep!, #sq_find_nondiv, #vertical_sweep!

Methods included from Enumerable

#all?, #any?, #collecti, #sum

Methods included from AlgebraBase

#**, #+@, #-@, append_features, #devide?, #ground, #ground=, #regulate, #unit?, #unity, #unity?, #zero, #zero?

Methods included from Orthogonalization

#normalize, #orthogonalize

Constructor Details

#initialize(array, conv = false) ⇒ MatrixAlgebra



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/algebra/matrix-algebra.rb', line 69

def initialize(array, conv = false)
  raise "rsize error (#{array.size} for #{rsize})" if array.size != rsize
  array.each do |v|
    raise "csize error (#{v.size} for #{csize})" if v.size != csize
  end
  if conv
    @bone = array.collect{|cv| cv.collect{|x|
        ground.regulate(x) or
          raise "initialize: unknown type #{x.class} (#{x})"
      }}
  else
    @bone = array
  end
end

Class Method Details

.*(otype) ⇒ Object

matrix type conversion



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/algebra/matrix-algebra.rb', line 114

def self.*(otype)
  if csize != otype.rsize
    raise "type error (#{self} * #{otype}, #{csize}:#{otype.rsize})"
  end

  if ground.respond_to?(:wedge)
    g = ground.wedge otype.ground
  elsif ground <= Numeric
    g = otype.ground
  else
    raise "*: unkown type conversion (#{ground}) * (#{oground})"
  end

  if otype <= Vector
    Algebra::Vector.create(g, rsize)
  elsif self <= Covector
    Algebra::Covector.create(g, csize)
  elsif rsize == otype.csize
    SquareMatrix.create(g, rsize)
  else
    MatrixAlgebra.create(g, rsize, otype.csize)
  end
end

.**(m) ⇒ Object



555
556
557
# File 'lib/algebra/matrix-algebra.rb', line 555

def self.**(m)
  m.convert_to(self)
end

.[](*a) ⇒ Object



104
105
106
# File 'lib/algebra/matrix-algebra.rb', line 104

def self.[](*a)
   new(a, true)
end

.collect_column(n = csize) ⇒ Object



434
435
436
437
# File 'lib/algebra/matrix-algebra.rb', line 434

def self.collect_column(n = csize)
  columns = (0...n).collect{|j| yield j}
  matrix{|i, j| columns[j][i]}
end

.collect_ij(m = rsize, n = csize) ⇒ Object



392
393
394
395
396
397
398
# File 'lib/algebra/matrix-algebra.rb', line 392

def self.collect_ij(m = rsize, n = csize)
  (0...m).collect do |i|
    (0...n).collect do |j|
	yield(i, j)
    end
  end
end

.collect_row(m = rsize) ⇒ Object



426
427
428
# File 'lib/algebra/matrix-algebra.rb', line 426

def self.collect_row(m = rsize)
  new((0...m).collect{|i| yield i})
end

.convert_from(m) ⇒ Object



551
552
553
# File 'lib/algebra/matrix-algebra.rb', line 551

def self.convert_from(m)
  matrix{|i, j| m[i, j].convert_to(ground)}
end

.create(ground, rsize, csize) ⇒ Object



234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/algebra/matrix-algebra.rb', line 234

def self.create(ground, rsize, csize)
  if klass = matrices[[ground, rsize, csize]] #flyweight
    klass
  else
    klass = super(ground)
    klass.sysvar(:sizes, [rsize, csize])
    klass.sysvar(:rsize, rsize)
    klass.sysvar(:csize, csize)
    matrices[[ground, rsize, csize]] = klass
    klass
  end
end

.dsum(otype) ⇒ Object



156
157
158
159
160
161
162
163
164
165
# File 'lib/algebra/matrix-algebra.rb', line 156

def self.dsum(otype)
  #unless ground == otype.ground
  #  raise "type error #{ground}.dsum #{otype.ground}"
  #end
  if self <= SquareMatrix and otype <= SquareMatrix
    superclass.create(ground, size + otype.size)
  else
    superclass.create(ground, rsize + otype.rsize, csize + otype.csize)
  end
end

.dsum_c(otype) ⇒ Object



169
# File 'lib/algebra/matrix-algebra.rb', line 169

def self.dsum_c(otype); raise "not implemented"; end

.dsum_r(otype) ⇒ Object



167
# File 'lib/algebra/matrix-algebra.rb', line 167

def self.dsum_r(otype); raise "not implemented"; end

.each_ijObject



349
350
351
352
353
354
355
# File 'lib/algebra/matrix-algebra.rb', line 349

def self.each_index
  (0...rsize).each do |i|
    (0...csize).each do |j|
	yield i, j
    end
  end
end

.each_indexObject



340
341
342
343
344
345
346
# File 'lib/algebra/matrix-algebra.rb', line 340

def self.each_index
  (0...rsize).each do |i|
    (0...csize).each do |j|
	yield i, j
    end
  end
end

.matricesObject



102
# File 'lib/algebra/matrix-algebra.rb', line 102

def self.matrices; Matrices; end

.matrix(m = rsize, n = csize) ⇒ Object



402
403
404
# File 'lib/algebra/matrix-algebra.rb', line 402

def self.matrix(m = rsize, n = csize)
  new(collect_ij(m, n) {|i, j| yield i, j})
end

.minorObject

def self.covector_type

  Algebra::Covector.create(ground, csize)
end


146
147
148
149
150
151
152
153
154
# File 'lib/algebra/matrix-algebra.rb', line 146

def self.minor
  if self <= SquareMatrix
    superclass.create(ground, size-1)
  elsif self <= MatrixAlgebra
    superclass.create(ground, rsize-1, csize-1)
  else
    raise "minor: unknown type #{self.class}"
  end
end

.regulate(x) ⇒ Object



319
320
321
322
323
324
325
326
# File 'lib/algebra/matrix-algebra.rb', line 319

def self.regulate(x)
  case x
  when Vector, Covector, MatrixAlgebra #,SquareMatrix
    x
  else
    nil
  end
end

.transposeObject



247
248
249
250
251
252
253
# File 'lib/algebra/matrix-algebra.rb', line 247

def self.transpose
  if sizes == [csize, rsize]
    self
  else
    superclass.create(ground, csize, rsize)
  end
end

.zeroObject



314
315
316
317
# File 'lib/algebra/matrix-algebra.rb', line 314

def self.zero
#    new((0...rsize).collect{(0...csize).collect{ground.zero}})
  matrix{ground.zero}
end

Instance Method Details

#*(other) ⇒ Object



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
# File 'lib/algebra/matrix-algebra.rb', line 473

def *(other)
  #without regulation!
  if other.is_a?(ground) || other.is_a?(Numeric)#1.is_a?(Rational) is false
    matrix{|i, j| self[i, j]*other}
  elsif self.is_a?(other.ground)
    other.matrix{|i, j| self*other[i, j]}
  else
    super{|o|
      msize = csize
      raise "type error" unless msize == o.rsize
      (self.class * o.class).matrix(rsize, o.csize){|i, j|
        (0...msize).sum(ground.zero){|k| self[i, k] * o[k, j]}
      }
    }
  end
end

#+(other) ⇒ Object



443
444
445
446
447
448
# File 'lib/algebra/matrix-algebra.rb', line 443

def +(other)
  super{ |o|
    raise "type error" unless sizes == o.sizes
    matrix{|i, j| self[i, j] + o[i, j]}
  }
end

#-(other) ⇒ Object



450
451
452
453
454
455
# File 'lib/algebra/matrix-algebra.rb', line 450

def -(other)
  super{ |o|
    raise "type error" unless sizes == o.sizes
    matrix{|i, j| self[i, j] - o[i, j]}
  }
end

#/(other) ⇒ Object



490
491
492
493
494
495
496
497
# File 'lib/algebra/matrix-algebra.rb', line 490

def /(other)
  case other
  when ground, Numeric
    matrix{|i, j| self[i, j] / other}
  else
    raise "(/): unknown type #{other.class}"
  end
end

#==(other) ⇒ Object



382
383
384
385
386
387
388
389
390
# File 'lib/algebra/matrix-algebra.rb', line 382

def ==(other)
  super{ |o|
    rais "type error" unless sizes == o.sizes
    each_index do |i, j|
	return false unless self[i, j] == o[i, j]
    end
    true
  }
end

#[](i, j) ⇒ Object

def [](i, j = nil)

  j ? @bone[i][j] : @bone[i]
end


178
179
180
# File 'lib/algebra/matrix-algebra.rb', line 178

def [](i, j)
  @bone[i][j]
end

#[]=(i, j, x) ⇒ Object



182
183
184
# File 'lib/algebra/matrix-algebra.rb', line 182

def []=(i, j, x)
  @bone[i][j] = x
end

#coerce(other) ⇒ Object

MatrixAlgebra



328
329
330
331
332
333
334
# File 'lib/algebra/matrix-algebra.rb', line 328

def coerce(other)#MatrixAlgebra
  if x = ground.regulate(other)
    [Algebra::Scalar.new(x), self]
  else
    super
  end
end

#cofactor(i, j) ⇒ Object



416
417
418
# File 'lib/algebra/matrix-algebra.rb', line 416

def cofactor(i, j)
  minor(i, j).determinant * (-1)**(i+j)
end

#cofactor_matrixObject Also known as: adjoint



420
421
422
# File 'lib/algebra/matrix-algebra.rb', line 420

def cofactor_matrix
  self.transpose.matrix{|i, j| cofactor(j, i)}
end

#collect_column(n = csize) ⇒ Object



439
440
441
# File 'lib/algebra/matrix-algebra.rb', line 439

def collect_column(n = csize)
  self.class.collect_columns(n){|j| yield j}
end

#collect_ij(*x, &b) ⇒ Object



400
# File 'lib/algebra/matrix-algebra.rb', line 400

def collect_ij(*x, &b); self.class.collect_ij(*x, &b); end

#collect_row(m = rsize) ⇒ Object



430
431
432
# File 'lib/algebra/matrix-algebra.rb', line 430

def collect_row(m = rsize)
  self.class.collect_row(m){|i| yield i}
end

#column(j) ⇒ Object



217
218
219
220
# File 'lib/algebra/matrix-algebra.rb', line 217

def column(j)
  raise "size error" unless 0 <= j && j < csize
  (0...rsize).collect{|i| @bone[i][j]}
end

#columnsObject



207
208
209
# File 'lib/algebra/matrix-algebra.rb', line 207

def columns
  (0...csize).collect{|j| column(j)}
end

#convert_to(mat_alg) ⇒ Object



547
548
549
# File 'lib/algebra/matrix-algebra.rb', line 547

def convert_to(mat_alg)
  mat_alg.matrix{|i, j| mat_alg.ground.regulate(self[i, j])}
end

#csizeObject



232
# File 'lib/algebra/matrix-algebra.rb', line 232

def csize; self.class.csize; end

#diagObject



537
538
539
540
541
542
543
544
545
# File 'lib/algebra/matrix-algebra.rb', line 537

def diag
  ed = []
  size = rsize < csize ? rsize : csize
  (0...size).each do |i|
    break if self[i, i].zero?
    ed.push self[i, i]
    end
  ed
end

#display(out = $stdout) ⇒ Object



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/algebra/matrix-algebra.rb', line 259

def display(out = $stdout)
  @bone.each do |col|
#      out << col.inspect << "\n"
    first = true
    col.each do |x|
	if first
 first = false
	else
 out << ", "
	end
	out << sprintf("%3s", x)
    end
    out << "\n"
  end
  out
end

#display_by_latex(out = $stdout) ⇒ Object



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/algebra/matrix-algebra.rb', line 276

def display_by_latex(out = $stdout)
#    out << "\\left(\n"
#    out "\\begin{array}{" + "c" * @bone[0].size + "}\n"
  @bone.each do |col|
#      out << col.inspect << "\n"
    first = true
    col.each do |x|
	if first
 first = false
	else
 out << " & "
	end
	out << sprintf("%3s", x)
    end
    out << "\\\\\n"
  end
#    out << "\\end{array}"
#    out << "\\right)"
  out
end

#dsum(other) ⇒ Object



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
# File 'lib/algebra/matrix-algebra.rb', line 509

def dsum(other)
  mytype = self.class.dsum(other.class)
  mytype.matrix{|i, j|
    if i < rsize
	if j < csize
 self[i, j]
	else
 other.ground.zero
	end
    else
	if j < csize
 ground.zero
	else
 other[i - rsize, j - csize]
	end
    end
  }
end

#dupObject



84
85
86
87
88
# File 'lib/algebra/matrix-algebra.rb', line 84

def dup
#    matrix{|x| self[* x.collect{|y| y.dup}]}
#    matrix{|x| self[* x.collect{|y| y}]} #in 1.8.0, Integer can't be dup..
  matrix{|i, j| self[i, j]} #in 1.8.0, Integer can't be dup..
end

#e_degObject



28
29
30
31
32
33
34
35
36
# File 'lib/algebra/elementary-divisor.rb', line 28

def e_deg
  max = -1
  each_ij do |i, j|
    if !self[i, j].zero? && (d = self[i, j].deg) > max
      max = d
    end
  end
  max
end

#each(&b) ⇒ Object



336
337
338
# File 'lib/algebra/matrix-algebra.rb', line 336

def each(&b)
  @bone.each(&b)
end

#each_columnObject



376
377
378
379
380
# File 'lib/algebra/matrix-algebra.rb', line 376

def each_column
  (0...rsize).each do |i|
    yield column(i)
  end
end

#each_iObject



358
359
360
361
362
# File 'lib/algebra/matrix-algebra.rb', line 358

def each_i
  (0...rsize).each do |i|
    yield i
  end
end

#each_index(&b) ⇒ Object Also known as: each_ij



352
353
354
# File 'lib/algebra/matrix-algebra.rb', line 352

def each_index(&b)
  self.class.each_index(&b)
end

#each_jObject



364
365
366
367
368
# File 'lib/algebra/matrix-algebra.rb', line 364

def each_j
  (0...csize).each do |j|
    yield j
  end
end

#each_rowObject



370
371
372
373
374
# File 'lib/algebra/matrix-algebra.rb', line 370

def each_row
  (0...rsize).each do |i|
    yield row(i)
  end
end

#flattenObject



532
533
534
535
# File 'lib/algebra/matrix-algebra.rb', line 532

def flatten
  #'to_a' is defined in Enumerable
  to_a.flatten
end

#i2oObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/algebra/elementary-divisor.rb', line 11

def i2o
  mground = self.class.ground.ground
  r = if self.class <= Algebra::SquareMatrix
        Algebra.SquareMatrix(mground, size)
      else
        Algebra.MatrixAlgebra(mground, rsize, csize)
      end

  rx = Algebra.Polynomial(r, 'x')
  x = rx.var
  s = 0
  (0..e_deg).each do |n|
    s += x**n * r.matrix { |i, j| self[i, j][n] }
  end
  s
end

#inspectObject



305
306
307
# File 'lib/algebra/matrix-algebra.rb', line 305

def inspect
  "#{self.class}#{to_s}"
end

#jordan_formObject



10
11
12
# File 'lib/algebra/jordan-form.rb', line 10

def jordan_form
  Algebra::JordanForm.decompose(self).first
end

#jordan_form_infoObject



14
15
16
# File 'lib/algebra/jordan-form.rb', line 14

def jordan_form_info
  Algebra::JordanForm.decompose(self)
end

#latex(env = "pmatrix") ⇒ Object



297
298
299
300
301
302
303
# File 'lib/algebra/matrix-algebra.rb', line 297

def latex(env = "pmatrix")
  s = ""
  s << "\\begin{#{env}}\n" if env
  s << display_by_latex("")
  s << "\\end{#{env}}\n" if env
  s
end

#mapObject



499
500
501
# File 'lib/algebra/matrix-algebra.rb', line 499

def map
  matrix{|i, j| yield(self[i, j])}
end

#matrix(m = rsize, n = csize) ⇒ Object



406
407
408
# File 'lib/algebra/matrix-algebra.rb', line 406

def matrix(m = rsize, n = csize)
  self.class.matrix(m, n){|i, j| yield i, j}
end

#minor(i, j) ⇒ Object



410
411
412
413
414
# File 'lib/algebra/matrix-algebra.rb', line 410

def minor(i, j)
  self.class.minor.matrix{|a, b|
    self[a < i ? a : a+1, b < j ? b : b+1]
  }
end

#old_mul(other) ⇒ Object



457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/algebra/matrix-algebra.rb', line 457

def old_mul(other)
  #without regulation
  case other
  when ground, Numeric # 1.is_a?(Rational) is false
    matrix{|i, j| self[i, j]*other}
  else
    super{|o|
      msize = csize
      raise "type error" unless msize == o.rsize
      (self.class * o.class).matrix(rsize, o.csize){|i, j|
        (0...msize).sum(ground.zero){|k| self[i, k] * o[k, j]}
      }
    }
  end
end

#orthogonal_basisObject



224
225
226
# File 'lib/algebra/gaussian-elimination.rb', line 224

def orthogonal_basis
  transpose.kernel_basis
end

#rankObject



219
220
221
222
# File 'lib/algebra/gaussian-elimination.rb', line 219

def rank
  n, k, pi = dup.left_eliminate!
  pi
end

#replace(m) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/algebra/matrix-algebra.rb', line 90

def replace(m)
  if m.is_a?(self.class) and sizes == m.sizes
    each_index do |i, j|
	@bone[i][j] = m[i, j]
    end
  else
    raise "Type Error #{m.class}"
  end
end

#row(i) ⇒ Object



190
191
192
193
# File 'lib/algebra/matrix-algebra.rb', line 190

def row(i)
  raise "size error" unless 0 <= i && i < rsize
  @bone[i].clone
end

#row!(i) ⇒ Object

column!(j) is not defined!



195
196
197
198
# File 'lib/algebra/matrix-algebra.rb', line 195

def row!(i) # column!(j) is not defined!
  raise "size error" unless 0 <= i && i < rsize
  @bone[i]
end

#rowsObject



186
187
188
# File 'lib/algebra/matrix-algebra.rb', line 186

def rows
  (0...rsize).collect{|i| row(i)}
end

#rsizeObject



231
# File 'lib/algebra/matrix-algebra.rb', line 231

def rsize; self.class.rsize; end

#set_column(j, array) ⇒ Object



222
223
224
225
226
227
# File 'lib/algebra/matrix-algebra.rb', line 222

def set_column(j, array)
  raise "size error" unless 0 <= j && j < csize
  raise "size error" unless rsize == array.size
  (0...rsize).each{|i| @bone[i][j] = array[i]}
  self
end

#set_row(i, array) ⇒ Object



200
201
202
203
204
205
# File 'lib/algebra/matrix-algebra.rb', line 200

def set_row(i, array)
  raise "size error" unless 0 <= i && i < rsize
  raise "size error" unless csize == array.size
  @bone[i] = array
  self
end

#simplifyObject



100
# File 'lib/algebra/matrix-algebra.rb', line 100

def simplify; matrix{|i, j| self[i, j].simplify}; end

#sizesObject



230
# File 'lib/algebra/matrix-algebra.rb', line 230

def sizes; self.class.sizes; end

#to_aryObject



528
529
530
# File 'lib/algebra/matrix-algebra.rb', line 528

def to_ary
  to_a
end

#to_quintObject



16
17
18
# File 'lib/algebra/matrix-algebra-triplet.rb', line 16

def to_quint
  Algebra::MatrixAlgebraQuint.new(self)
end

#to_sObject



255
256
257
# File 'lib/algebra/matrix-algebra.rb', line 255

def to_s
  @bone.inspect
end

#to_tripletObject



12
13
14
# File 'lib/algebra/matrix-algebra-triplet.rb', line 12

def to_triplet
  Algebra::MatrixAlgebraTriplet.new(self)
end

#transposeObject Also known as: t



503
504
505
# File 'lib/algebra/matrix-algebra.rb', line 503

def transpose
  self.class.transpose.matrix(csize, rsize){|i, j| self[j, i]}
end

#typesObject

check entries



310
311
312
# File 'lib/algebra/matrix-algebra.rb', line 310

def types
  matrix{|i, j| self[i, j].class}
end

#vectorsObject



211
212
213
214
215
# File 'lib/algebra/matrix-algebra.rb', line 211

def vectors
#    vc = self.class.vector_type
  vc = Algebra::Vector.create(ground, rsize)
  columns.collect{|v| vc[*v]}
end