[완료] 간단한 루비 질문입니다.

isty2e의 이미지

positive eigenvalue를 가진 n by n matrix를 만들려고 해서 다음과 같이 짜 봤습니다.

require 'matrix'

print "Enter the dimension of the matrix:"
begin
dim=Integer(gets)
rescue ArgumentError
puts "This is not an integer!"
end

def dot_product(vec1, vec2)
sum=0
0.upto(vec1.size-1) {|i| sum+=vec1[i]*vec2[i]}
return sum
end

def norm(vec)
return Math.sqrt(dot_product(vec, vec))
end

def normalize(vec)
return vec*1/norm(vec)
end

def GramSchmidt(vecs)
new_vecs=[]
new_vecs << normalize(vecs[0])
1.upto(vecs.size-1) do |i|
new_vecs << vecs[i].clone
1.upto(i-1) do |j|
new_vecs[i]-=new_vecs[j]*dot_product(new_vecs[i], new_vecs[j])
end
end
return new_vecs
end

rand_nums=[]
dim.times {rand_nums << rand(10)+1}
diag_mat=Matrix.diagonal(rand_nums)

rand_vecs=[]
dim.times do
vec=[]
dim.times {vec << rand}
rand_vecs << vec
end

rot_mat=GramSchmidt(Vector[rand_vecs])

mat=rot_mat.t*diag_mat*rot_mat

그런데

asdf.rb:12:in `*': can't convert Array into Integer (TypeError)
from asdf.rb:12:in `dot_product'
from asdf.rb:12:in `upto'
from asdf.rb:12:in `dot_product'
from asdf.rb:17:in `norm'
from asdf.rb:21:in `normalize'
from asdf.rb:26:in `GramSchmidt'
from asdf.rb:51

가 뜨네요. 제가 보기엔 number*number로 보이는데 뭐가 문제인지 모르겠습니다. 아직 루비 문법에 익숙치 않아서 저걸 해결한다고 코드가 잘 작동할지도 의문이네요...

그리고 뭔가 코드를 지저분하게 짠 것 같은데 우아하게 정리하려면 어떻게 될지도 알고 싶습니다.

익명 사용자의 이미지

익명 사용자의 이미지

0.upto(vec1.size-1) {|i| sum+=vec1[i]*vec2[i]} 을 보면
vec1 이라는 array 에 array 가 들어가 있습니다.(예 [ [0.22882944], [0.358388] ]
따라서 vec1[i] 는 array 이고 vec1[i] * vec2[i] 은 당연히 에러.

이 문장을
0.upto(vec1.size-1) {|i| sum+=vec1[i]*vec2[i]}
이렇게 바꿔도
vec1.size.times { |i| sum + = vec1[i] * vec2[i] } # i 값은 0...vec1.size 까지, 또는 0..(vec1.size-1)
vec1[i] 가 array 인 관계로 에러가 발생하겠지만, 위 문장과 의미는 동일합니다.

나머지는 수학이므로 다음 분께 패스

isty2e의 이미지

수학을 잘못 짜고 있었군요 -_-; 부끄럽네요.

isty2e의 이미지

require 'matrix'

print "Enter the dimension of the matrix:"
begin
dim=Integer(gets)
rescue ArgumentError
puts "This is not an integer!"
end

class Matrix
#this method is required due to poor definition of matrices in ruby
def Matrix.diagonal(values)
size=values.size
rows=(0..size-1).collect {
|j|
row=Array.new(size).fill(0, 0, size)
row[j]=values[j]
row
}
rows(rows, false)
end
end

def dot_product(vec1, vec2)
sum=0
0.upto(vec1.size-1) {|i| sum+=vec1[i]*vec2[i]}
return sum
end

def norm(vec) Math.sqrt(dot_product(vec, vec)) end

def normalize(vec) vec.map{|i| i/norm(vec)} end

def gen_rand_vecs(dim) Array.new(dim) {Array.new(dim) {rand}} end

def GramSchmidt(vecs)
dim=vecs.size
new_vecs=[]
new_vecs << normalize(vecs[0])
(1...dim).each do |i|
new_vec=vecs[i].clone
(0...i).each do |j|
dot=dot_product(new_vec, new_vecs[j])
(0...dim).each {|k| new_vec[k]-=new_vecs[j][k]*dot}
end
new_vecs << normalize(new_vec)
end
return new_vecs
end

def print_mat(mat)
dim=mat.rank
(0...dim).each do |i|
puts Array.new(dim) {|j| sprintf("%4f", mat[i, j])}.join("\t")
end
end

diag_mat=Matrix.diagonal(Array.new(dim) {rand})
rot_mat=Matrix.rows(GramSchmidt(gen_rand_vecs(dim)))
#puts rot_mat.det
mat=rot_mat.t*diag_mat*rot_mat

puts "Diagonal matrix:"
print_mat(diag_mat)
puts "\nRotation matrix:"
print_mat(rot_mat)
puts "\nRotated matrix:"
print_mat(mat)

혹시 나중에 참고하실 분이 계신가 하여...

루비에서 Vector와 Matrix 클래스는 부실하군요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.