SVDPACKC

どうでもいいですが,hatena diary みたいに*で自動トピック分けって出来ないんですかね...
まあ,出来るのかも知れませんが調べてない僕が悪いわけでw
さて,本題です.
仕事と言っていいのか分かりませんが,行列演算ライブラリで
 SVDPACKC
っていうのがあります.ITコンサルタントAさんの依頼で,ソースコードをちょいとハックしました.
ハックの参考にしたのが,以下のページのPDFです
 Introduction of SVDPACKC
さて,この参考文献では las2 というアルゴリズムの中でおかしな部分を直して,ついでに行列演算の結果をテキストに吐きだしてやろう,という変更を行うことを指摘しています.
しかも,かなーり丁寧に直してくれています.
SVDPACKCでぐぐってきたりしたひとが居るかどうか分かりませんが,ご存じの通りセグメンテーションフォールトの嵐でかなり困ったことになります.
なお,試した環境は x86 VineLinux3.2CR と Cygwin です.
というわけで,せっかく動くように直したのでそのメモをここに残すことにしました.
ちなみに,patch 作成でもよかったんですが Windows で頑張る人のためにもあえて変更箇所明記にとどめておきます.
# patch 作ったことがないってのが正しい言い訳ですがw
なお,上記PDFで変更してくれている部分も書いているので,確認の意味も含めてお使いください.
— 以下変更箇所 —
— 更新後のみ書いてますので, コメントアウトを探してみてください.–
@las2.h

  ・・・
  //long    fp_out2;
  FILE     *fp_out2 = NULL;
  ・・・
  FILE     *fp_out3 = NULL;

@las2.c

  ・・・ L.5 付近
  // #include 
  
  ・・・ L.144 付近
  // user variable
  long kk;
  fp_out3 = fopen("V_matrix", "w");
 
  ・・・ L.174 付近
  //#if !defined UNIX_CREAT
  //       if ((fp_out2 = open(out2, O_CREAT | O_RDWR)) == -1) {
         if ((fp_out2 = fopen("out2", "w")) == NULL) {
 
  ・・・ L.179 付近
         /*
  #else
         if ((fp_out2 = creat(out2, PERMS)) == -1) {
            printf("cannot open output file %s ¥n", out2);
            exit(-1);
         }
  #endif
         */
 
  ・・・ L.204 付近
  //       if (vectors) close(fp_out2);
         if (vectors) fclose(fp_out2);
 
  ・・・ L.275 付近
      if (vectors) {
         free(xv1);
         free(xv2);
  //       close(fp_out2);
         fclose(fp_out2);
 
  ・・・ L.334 付近
           //      write(fp_out2, (char *)&xv1[ida], size1);
           for (kk = 0; kk < nrow; kk++) {
             fprintf(fp_out2, "%lf¥t",xv1[ida+kk]);
           }
           fprintf(fp_out2, "EOV¥n");
 
  ・・・ L.387 付近
  //        close(fp_out2);
          fclose(fp_out2);
 
  ・・・ L.394 付近
  //extern FILE *fp_out1;
  extern FILE *fp_out1, *fp_out2;
 
  ・・・ L.641 付近
  //extern long nrow, ierr, j, fp_out2, nsig, neig;
  extern long nrow, ierr, j, nsig, neig;
 
  ・・・ L.731 付近
     /*
     write(fp_out2, (char *)&n, sizeof(n));
     write(fp_out2, (char *)&js, sizeof(js));
     write(fp_out2, (char *)&kappa, sizeof(kappa));
     */
  
     fprintf(fp_out2, "%i", n);
     fprintf(fp_out2, "%i", js);
     fprintf(fp_out2, "%f", kappa);
 
  ・・・ L.747 付近
  //         write(fp_out2, (char *)w1, size);
          fprintf(fp_out2, "%f", w1);
 
  ・・・ L.756 付近
          //         for (i = 0; i < n; i++) xv1[id++] = w1[i];
          for (i = 0; i < n; i++) {
            xv1[id++] = w1[i];
            fprintf (fp_out3, "%lf¥t", w1[i]);
          }
  
          fprintf (fp_out3, "EOV¥n");

-- 変更終わり --
さすがに大量ですねw ラインナンバーも改変しすぎちゃって何とも言えないんですよねw
とりあえず誰かの参考になれば...と思います.
ちなみに,何をいじってるのかと言いますと fp_out2 が long になっているので,かなり昔のCの書き方がされています.
# だってファイルポインタじゃないのか,と...
それを FILE* に直しただけです,はい.
意外とめんどくさいですが,頑張りました.

コメント

  1. 匿名 より:

    まったく同じ問題で困っていたので大変参考になりました。上記の修正でちゃんと動きました!

  2. こぐち より:

    >名無しさん
    実は知人以外の初コメでした。
    お役に立てて何よりです。

  3. 匿名 より:

    SVDPACKCのランチョスアルゴリズムあたりをJavaにポーティングしたら喜ばれるのでしょうか?

  4. こぐち より:

    >名無しさん
    上の名無しさんと同一人物かな?
    うーん、SVDPACKCがどの程度有用なライブラリなのか分かっていないので、その辺の需要はどうなんでしょう。
    純粋にスキルだけの話をすると、そんなに複雑なことをやっているソースには見えなかったので、Portingはいけるかもしれませんね。

タイトルとURLをコピーしました