Rubyで行列式の計算について

このQ&Aのポイント
  • Rubyでcsvファイルから行列の値を読み込んで、行列式の乗算をしたいです。
  • エラーが出てしまい困っています。
  • 解決法を教えていただければ助かります。
回答を見る
  • ベストアンサー

Rubyでの行列式の計算について

Rubyでcsvファイルから行列の値を読み込んで、 行列式の乗算をしたいのですがエラーがでて困っています。 例えばA.csvがcsvファイルの形式で100行20列の行列でB.csvもcsvファイルの形式で20行3列の行列としたとき、 require 'matrix' require 'csv' ma = CSV.read(A) mb = CSV.read(B) mc = ma * mb print mc, "\n" と入力すると、":in `*': can't convert Array into Integer (TypeError)" というエラーが出てしまいます。 プログラミング初心者なので根本的なところが理解できていないかも知れませんが、解決法を教えていただければ助かります。 よろしくお願いいたします。

  • Ruby
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

基本的なところで2点。 その1: CSV.read(A) で読み込んだ物は、配列の配列で、マトリクスとは違います。 Matrix.rows() 等でマトリクスに変換が必要。 その2: CSV.read(A) で読み込んだ物の配列の要素は文字列です。数値ではありません。 文字列から数値に変換しないと演算できません。 ma = Matrix.rows(CSV.read(A)).map{|x| x.to_i} mb = Matrix.rows(CSV.read(B)).map{|x| x.to_i} mc = ma*mb

ifrenzy
質問者

お礼

解決できました!! 本当にありがとうございました!!

関連するQ&A

  • 部分行列の抜き出し(C言語)

    部分行列の抜き出し(C言語) ある行列から、任意の部分行列を抜き出すような関数を作りたいのですが、わからないので手助けをお願いしたいです。 たとえば4行4列の行列Aがあった場合、その2行2列、2行3列、3行2列、3行3列目の 4つの(2行2列の)要素を抜き出すような関数です。 枠組みは出来ているので載せておきます。 #include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct matrix{ double *data; int size[2]; }MATRIX; MATRIX create_matrix(int m,int l,int a); //行列の作成 void print_matrix(MATRIX A); //行列の表示 MATRIX submatrix(MATRIX matrix_A,int m,int n,int l,int k); //任意の部分行列の抜き出し int main(int argc,char **argv) { //構造体の初期化 MATRIX matrix_A={NULL,NULL,NULL}; MATRIX matrix_B={NULL,NULL,NULL}; MATRIX matrix_C={NULL,NULL,NULL}; int m=0; //行列の行 int l=0; //行列の列 int a=1; //要素 double det=0; //行列計算 //行列Aの作成 m=4;//行 l=4;//列 matrix_A = create_matrix( m, l, a); //関数 matrix_C = submatrix(matrix_A,2,2,3,3); //行列結果出力 printf("\n\tmatrix input"); print_matrix(matrix_A); printf("\n\tmatrix output"); print_matrix(matrix_C); //行列の開放 free(matrix_A.data); matrix_A.data=NULL; free(matrix_C.data); matrix_C.data=NULL; printf("終了!\n\n"); return 0; } MATRIX create_matrix(int m,int l,int a) { MATRIX matrix_A={NULL,NULL,NULL}; int i=0; //サイズの確保 行;size[0] 列;size[1] matrix_A.size[0]=m; matrix_A.size[1]=l; //メモリの確保 matrix_A.data=(double *)malloc(sizeof(double)*matrix_A.size[0]*matrix_A.size[1]); if(matrix_A.data == NULL){ printf("メモリ確保失敗!![matrix_A]\n"); exit(1); } //行列Aの作成 for(i=0; i<((matrix_A.size[0])*(matrix_A.size[1])) ;i++){ *(matrix_A.data+i)=a+i; } return(matrix_A); } /*行列の表示*/ void print_matrix(MATRIX matrix_A) { int i=0; int j; //行 int k; //列 printf("\n行列の表示\n"); //行列Aのプリント for(j=0;j<matrix_A.size[0];j++){ for(k=0;k<matrix_A.size[1];k++){ printf("%f\t",*(matrix_A.data+k*matrix_A.size[0]+j)); } printf("\n"); } return; } MATRIX submatrix(MATRIX matrix_A,int m,int n,int l,int k) { MATRIX matrix_C = {NULL,NULL,NULL}; int i,j; //サイズの確保 行;size[0] 列;size[1] matrix_C.size[0]=l-m+1; matrix_C.size[1]=k-n+1; //メモリの確保 matrix_C.data=(double *)malloc(sizeof(double)*matrix_C.size[0]*matrix_C.size[1]); if(matrix_C.data == NULL){ printf("メモリ確保失敗!![matrix_C]\n"); exit(1); } //任意の部分行列の抜き出し (ここがわかりません。) } よろしくお願いします。

  • 行列をベクトルに

    m行n列の行列Aがあったとき、それをm×n行1列の行列(ベクトル)Bに するというプログラムを作りたいです。 つまり MATRIX B; B.m=A.m*A.n; B.n=1; return B; ということだと思うのですが、なかなかうまいくいきません。 また、構造体も使いたいので、 typedef struct { int m; int n; double *mat; } MATRIX; と宣言しました。 みなさんよろしくお願いします。

  • 行列をベクトルに(C言語)

    行列をベクトルに(C言語) m行n列の行列Aがあったとき、それをm×n行1列の行列(ベクトル)Bに するというプログラムを作りたいです。 これは、行列Aの1列目m行分の要素をそのまま行列Bの1行1列目に持っていき、 それを行列Aのn列の数だけ繰り返す、といった要領です(画像参照) つまり MATRIX B; B.m=A.m*A.n; B.n=1; return B; ということだと思うのですが、なかなかうまいくいきません。 また、構造体も使いたいので、 typedef struct { int m; int n; double *mat; } MATRIX; と宣言しました。 画像は説明のため、一応載せておきました。(例として4列の行列になっています) みなさんよろしくお願いします。

  • エクセルでの行列計算がうまくいきません

    よろしくお願いします。 いまエクセルで行列計算をしています。 行列[108(行)×35(列)]とその転置行列[35×108]の積から行列[108×108]を出そうとしているのですがうまくいきません。 #valueエラーがでます。 関数mmultを使用しています。 転置行列は関数transposeを使いました。 [35×108]・[108×35]=[35×35]ではちゃんとでるのですが、108×108ではだめなので、元データには問題はないと思います。 一体何がエラーの原因として考えられるのでしょうか。 よろしくお願いします。

  • 英語で『m行n列の行列』の読み方

    m行n列の行列の英語表現の場合、書くだけなら、 m×n matrix でいいと思うのですが、(もしかしたらこの時点で違うかもしれませんが・・・) これはなんと読めばいいのでしょうか?

  • 転置行列への変換が分かりません。

    転置行列への変換が分かりません。 現在、type型のrow行column列の行列(row >= 2, column >= 2, row != column)を、要素数がrow * column個ある配列arrayを用いて表現しています。更にR行C列目の要素はrow * C + R番目のarrayの要素で示しています。 そして転置行列ですが、行列type^(row * column)と行列type^(column * row)は要素数が同じなのでarrayと同じサイズの配列を用いて表現が可能ですし、ひとつずつ要素の置換を行えば新しく一時的にtype^(column * row)の行列を作って単純に代入処理をするよりもメモリに負担が掛からないはずです。 よって今は以下のアルゴリズムを考案し実装したのですが、問題が発生しました。 (以下配列i番目の要素をarray[i - 1]、行列matrixのa行b列の要素はmatrix[a - 1][b - 1]と記す。) ---- 入力 matrix in type^(row * column)とresult_matrix in type^(column * row)を示す、row * column個の要素を持つarrayが与えられる。 手順1 変数xに1を、変数yに0を代入する。一時要素領域tmp_elemにmatrix[x][y] = array[x + y * row]を代入する。 手順2 result_matrix[y][x] = array[y + x * column]とtmp_elemを交換する。 手順3 変数tにy + x * columnを代入し、xにtとrowの剰余を、yにtをrowで割った値の整数部を代入する。 手順4 xが1でかつyが0なら終了。そうでなければ手順2から再度処理を実行。 ---- 分かりやすく書くと、与えられた始点の位置にある転置前の行列としての要素を取得し、次に行列を既に転置された形のものとみなしてから、さっき取得した要素を転置後にあるべき場所へと移動させ、そこに元々あった要素に対して更に再帰的に手順を適応する感じです(実装ではループに落としていますが)。終了条件は「交換対象が始点へ戻ってきたとき」です。 しかし、次々と交換していく流れにおいて処理されない要素が出てきました。integer^(10 * 5)における以下の行列 ---- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ---- の転置(仮) ---- 0, 10, 20, 30, 40, 1, 11, 7, 31, 41, 2, 12, 22, 32, 14, 3, 13, 23, 33, 43, 4, 21, 24, 34, 44, 5, 15, 25, 28, 45, 6, 16, 26, 36, 46, 35, 17, 27, 37, 47, 8, 18, 42, 38, 48, 9, 19, 29, 39, 49, ---- です。 ここではメインの流れmatirx[1][0] -> ... -> matrix[0][1]では走査できない要素の流れとして matrix[5][3] -> matrix[8][2] -> matrix[2][4] -> matrix[4][1] -> matrix[1][2] -> matrix[7][0] が存在しますが、検出できなかったこの流れにどの様な規則性があるのかどうかが分からないままです。 行列を転置行列に一時行列なしで変換する方法と、このアルゴリズムの不完全な部分を教えてください。 ><;

  • 行列の対角化について

    実対称行列A:= | 0 1 2 | | 1 1 3 | | 2 3 0 | に対し、tPAPが対角行列となるような実正則行列Pはどのように求めればよいのでしょうか? この場合は、固有値&固有ベクトルが簡単には求まらないので、簡単には対角化のための行列が求まりません。(たいていの問題では求まるんですが。) このような時は実二次形式を利用して解く、というような事は、色々見るのですが、いざやってみると行列Aの第1行第1列が"0"である事が非常に扱いづらいのです。つまり基本行変形だけで三角行列に変形できないのです。 どなたか教えていただけないでしょうか?

  • RubyでCSVファイルの1行目を削除したい 

    Rubyの初心者でSeleniumを使ってスクレイピングを趣味としてしているものです。 ブラウザはchromeです。 この間、例外が上がったときに一定回数リトライする方法をご伝授頂きました。 http://okwave.jp/qa/q8722965.html そしてそれを活用して、CSVにスクレイピングをしたいURLを1列目に並べ、複数のページをスクレイピングしているのですが、 def try(n=10) require 'pp' require 'csv' require 'selenium-webdriver' require 'open-uri' hoge_path = File.expand_path('../hoge.csv',__FILE__) driver = Selenium::WebDriver.for :chrome #chrome のdriverを設定 CSV.foreach(hoge_path) do |row| driver.navigate.to row[1] #URL移動 #ページの移動など driver.quit #ブラウザ終了 driver = Selenium::WebDriver.for :chrome #chrome のdriverを設定 end rescue => e if n==0 raise e driver.quit #ブラウザ終了 else driver.quit #ブラウザ終了 try(n-1) end end try よく仕組みを理解できていないのですが、CSV.foreach内はループされます。 そして、404エラーなどで落ちるとまた一行目に戻ってスクレイピングが行われ、非常に困っています。 そこで、CSVファイルの1行目をループするまたは例外のリトライの際に削除していけば良いと考えたのですが、一行目を削除するというコードをどう書けばいいのか分かりません。 どうかご伝授お願いします。

    • ベストアンサー
    • Ruby
  • 大量のCSVデータを行列の変換をしてエクセルデータにまとめる方法について

    CSVファイルが4000個ほどあり、VBAを用い、そのファイルの行列変換をして、1つのエクセルファイルにまとめたいのですが、うまくいきません。どなたか教えていただけないでしょうか? CSVファイルは、以下の様な2列200行位あるものを、2列目のみ取り出し、エクセルファイルには1行(列ではなく)にして取り出したいのです。 変換前データー A列   B列 B013 毛 B014 54 B015 ポリエステル B016 36 B017 絹 B018 10 B020 0 B022 0 B023 ポリエステル B024 0 B025 キュプラ B026 0 B028 0 B030 0 B032 0  ・  ・  ・  ・  ・  ・ 取り込み変換後データ 1行: 毛 54 ポリエステル 36 絹 10 0 0 ポリエステル 0 キュプラ 0 0 0 0 のようにしたいのです。 どなたかお教えいただけないでしょうか? よろしくお願いいたします。

  • 行列内の行の交換,列の交換をするプログラム

    行列内の行の交換,列の交換を行うプログラムを作成しています. http://www.math.meiji.ac.jp/~mk/lecture/ouyousuurijikken/matrix-lib-v2/node20.html のページにある方法で行交換はすることができたのですが,列交換をする方法がわかりません. 上のサイトのやり方を改造して,どうにか列交換をすることはできないのでしょうか? 分かる方おられましたら回答ください. よろしくお願いします.

専門家に質問してみよう