Reputation: 11
I am trying to define Ruby classes for vectors and matrices. I intend to define two classes, MyVector
and MyMatrix
, with methods as hinted below. MyVector
should represent a row vector, MyMatrix
should represent a matrix, internally organized as an array of MyVector
objects. Intended methods for MyVector
:
#initialize
method, that takes an array of integers as argument.#length
method, that returns the size of the vector.#*
method, taking argument a
, that:
a
is a vector, returns the inner product, validating that the size of a
matches the receiver.#to_s
method, that returns a string representation of the receiver.Methods for MyMatrix
:
#initialize
method, that takes an array of arrays as argument, converts the inner arrays into row vecotrs (MyVector
class), and arranges them into a matrix.#transpose
method, that returns the receiver transposed.#*
method, that takes MyMatrix
object argument and returns the matrix product, validating size compatibility of the argument.#to_s
method, that returns a string representation of the receiver.This code I have written so far is below, but it doesn't work at all. I tried to define some method followed by the library class method (in matrix and vector class, they already define those method), but seem this way doesn't work because it always asks you to define something new. Could you please help me? Thanks!
class MyVector
def initialize (a)
if !(a.instance_of? Array)
raise "must be an array"
else
@array = a
end
end
def array
@array
end
def to_s
@array.to_s
end
def length
@array.length
end
def each2(a) #
raise Error, "Integer is not like Vector" if a.kind_of?(Integer)
Vector.Raise Error if length != a.length
return to_enum(:each2, a) unless block_given?
length.times do |i|
yield @array[i], a[i]
end
self
end
def * (a)
Vector.Raise Error if length != a.length
p = 0
each2(a) {|a1, a2|p += a1 * a2}
p
end
end
class MyMatrix
def initialize a
@array=Array.new(a.length)
i=0
while(i<a.length)
@array[i]=MyVector.new(a[i])
end
end
def to_s
@array.to_s
end
def transpose
size=vectors[0].length
arr= Array.new(size)
i=0
while i<size
a=Array.new(vector.length)
j=0
while j<a.length
a[j]=vectors[j].arr[i]
j+=1
end
arr[i]=a
i+=1
end
arr[i]=a
i+=1
end
def *m
if !(m instance_of? MyMatrix)
raise Error
a=Array.new(@array.length)
i=0
while (i<@array.length)
a[i]=@array[i]*m
i=i+1
end
end
end
end
Upvotes: 0
Views: 120
Reputation: 12578
A great question, and a great exercise for a newbie. As you might already know, Marc-André Lafortune has written the basic Matrix / Vector library, that is a part of Ruby standard library. While after the amount of effort that a programmer and mathematician, that Marc-André is, has put in the project, it is no longer possible to say that it sucks, it is also fair to say that stdlib matrix
nowadays does not yet conform to that heavenly, dream-like quality that we expect of Ruby libraries.
My major criticism is that, just like you, Marc-André also makes a distinction between Vector
and Matrix
classes. This distinction shouldn't be: Vectors are simly matrices, whose second dimension is equal to 1. Separating Matrix
and Vector
leaves the user at loss as to which one to use, and that led me to banning Vector
completely in the code that I write.
Neveretheless, it will be stdlib's matrix
, that is going to be the answer to your post. If I understood it well, the question mark statement in your post seems to be:
"I tried to define some method ... but seem this way doesn't work because it always asks you to define something new. Could you please help me?"
In order to help you, I would answer: Start by using the matrix
standard library. Simply type
require 'matrix'
In the next step, you will make a private copy of matrix
library, that came with your Ruby installation, you will rename it to my_matrix
, and require it no longer by require 'matrix'
, but by:
require './path/to/my/project/directory/my_matrix'
In the third step, you will start changing the behavior of the library that you just copied, and see when it breaks. Next, you will learn about unit testing, and learn to use stdlib's minitest
. With that, you can define the desired behavior, and change the code until it meets the requirement.
In the 4th, 5th, ... nth step, you will be making a lot of big and small mistakes. And should your dedication to matrices and vectors in Ruby survive, you will be warmly welcome as a member of NMatrix
team, the future grand version of representing matrices in Ruby.
Upvotes: 3