アプリ版:「スタンプのみでお礼する」機能のリリースについて

プログラミングが得意な方お願いします。

下図のリンクのページランクをPerlで実装したいのですが、
まずPDLモジュールをダウンロードし、リンク隣接行列を下記のように定義しました。

use PDL::Lite;
my $mat1 = pdl [
[0, 1, 1/2, 0, 1/4, 1/2, 0],
[1/5, 0, 1/2, 1/3, 0, 0, 0],
[1/5, 0, 0, 1/3, 1/4, 0, 0],
[1/5, 0, 0, 0, 1/4, 0, 0],
[1/5, 0, 0, 1/3, 0, 1/2, 1],
[0, 0, 0, 0, 1/4, 0, 0],
[1/5, 0, 0, 0, 0, 0, 0]
];

そして下記の列ベクトルと上記の行列をかけてその答えと上記の行列をかけてさらにその答えと上記の行列をかけて・・・を繰り返し、掛けても答えが変わらなくなったところでその列ベクトルの値を取り出し正規化して出力するという方法を考えました。
my $mat2 = pdl [
[1],
[1],
[1],
[1],
[1],
[1],
[1]
];

ここで質問ですが、上記の処理をwhile文で実行したいのですが掛けても答えが変わらなくなったところでwhileからループを抜ける処理はどのように書いたら良いのでしょうか?

Perlは初心者で、行列同士の比較はwhileの条件文ではできないでしょうし、列ベクトルの要素を一つ一つ比較する方法も分かりません。

以上写真のページランクをperlで取得する方法、宜しくお願い致します。

「Perlでページランクを取得する方法」の質問画像

A 回答 (5件)

use PDL::Ufunc;


を追加し、次でループ脱出

if(all $ans_now == $ans_before){last;}

ただし、$ans_nowは今回の演算結果, $ans_beforeは前回の演算結果

PDLのhelp allより:
=======================
Module PDL::Ufunc
all
Return true if all elements in piddle set
  ...(snip)
=======================
    • good
    • 0

なんかもったいないことをしてる気がする>#3.



approx とか all とか駆使すればいいような.
    • good
    • 0

表示がくずれるので、空白2文字を全角空白にしていることに注意。



use feature 'say';
use PDL;

my $matrix1 = pdl( [ [ 1, 2 ], [ 3, 4 ] ] );
print '--- matrix1', $matrix1;
# --- matrix1
# [
# [1 2]
# [3 4]
# ]

my $vector1 = pdl( [ [5], [6] ] );
print '--- vector1', $vector1;
# --- vector1
# [
# [5]
# [6]
# ]

my $answer = $matrix1 x $vector1;
print '--- answer', $answer;
# --- answer
# [
# [17]
# [39]
# ]

my $vector2 = pdl( [ [7], [8] ] );
print '--- vector2', $vector2;
if ( compare_vector($vector1,$vector2) ) {
  say '$vector1 == $vector2';
}
else {
  say '$vector1 != $vector2';
}
# --- vector2
# [
# [7]
# [8]
# ]
# $vector1 != $vector2

my $vector3 = pdl( [ [5], [6] ] );
print '--- vector3', $vector3;
if ( compare_vector($vector1, $vector3) ) {
  say '$vector1 == $vector3';
}
else {
  say '$vector1 != $vector3';
}
# --- vector3
# [
# [5]
# [6]
# ]
# $vector1 == $vector3

sub compare_vector {
  my $v1 = shift;
  my $v2 = shift;

  if ($v1->getndims != $v2->getndims) {
    return 0;
  }

  my $dims = $v1->getndims;
  for (my $i = 0; $i < $dims; $i++) {
    if ($v1->at(0, $i) != $v2->at(0, $i)) {
      return 0;
    }
  }
  return 1;
}
    • good
    • 0

えぇと....



あなたは 2つの列ベクトルが同じかどうか判断することができますか?

この回答への補足

mat1×mat2を実行し、その答え(当然7行1列)にさらにmat1をかけ、その掛けた答えにさらにmat1を掛けるという動作を繰り返していくと、いずれその答えがほとんど変わらなくなります。その部分で、whileなりfor文から抜け出してその変わらなくなった答え(当然7行1列)を出力したいのです。

そのプログラムを教えて頂けたら幸いです。

補足日時:2014/08/09 22:41
    • good
    • 0

課題なのか何なのかよくわかりませんが、


ここで聞いてバレたら面倒なことになるとは想像できないんですか?

この回答への補足

課題ではありません。

mat1×mat2を実行し、その答え(当然7行1列)にさらにmat1をかけ、その掛けた答えにさらにmat1を掛けるという動作を繰り返していくと、いずれその答えがほとんど変わらなくなります。その部分で、whileなりfor文から抜け出してその変わらなくなった答え(当然7行1列)を出力したいのです。

そのプログラムを教えて頂ければ幸いです。

PDLをダウンロードしました。

補足日時:2014/08/09 22:42
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!