mots quotidiens.
Daichi Mochihashi (持橋大地) daichi <at> ism.ac.jp by hns, version 2.10-pl1.

先月 2004年10月 来月
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

2004年10月26日(火) [n年日記]

#1 -

class unigram のスムージング係数に対する Newton 法を導いたのはいいけど (というのが下のPDFの内容), 実際にコードしてみると動かない。
関数自体は独立に動かすと動くので, 合っているはずなのだけど。 何でだ。;_;
というわけでデバッグのためにさらしてみる。 ldabayes.m newton_eta.m

#2 "Numerical matrices in C"

Cでは一応多次元配列が使えるが, double matrix[10][20] のように コンパイル時に決まっていない場合は, 普通は matrix[i][j] のようにはアクセスでき ない。
列ごとに1行を malloc して割り付ければアクセスできるが, 10000x1000の行列なら 10000回 malloc することになるわけで, メモリ上で断片化が起きるし, malloc のオーバヘッドがありそうなので良くないかと思っていた。 (& 原理的に連続なものを断片的に malloc するのは良くないという気もした。)
そうでないと, matrix = (double *)malloc(rows * cols * sizeof(double)); のように確保する ことになるが, これは matrix[i][j] ではアクセスできない。
仕方がないので, これまで
#define  LZS(i,j)       (*(lzs + K * i + j))
のようにマクロを定義して使っていたが, 家に帰って, 前にPCに保存しておいた C FAQ (fj.lang.c に定期的に流れていたもの) を読んでいたら, 以下のようなコードを書くと, matrix[i][j] でアクセスできることを知った。
/*
    dmatrix.h
    a header file of double matrix.
    $Id: dmatrix.h,v 1.1 2004/10/26 05:04:21 dmochiha Exp $
*/
#ifndef __DMATRIX_H__
#define __DMATRIX_H__

extern double **dmatrix(int rows, int cols);

#endif
/*
    dmatrix.c
    an implementation of double matrix.
    $Id: dmatrix.c,v 1.1 2004/10/26 05:04:20 dmochiha Exp $
*/
#include <stdlib.h>
#include "dmatrix.h"

double **
dmatrix (int rows, int cols)
{
        double **matrix;
        int i;

        matrix = (double **)malloc(rows * sizeof(double *));
        if (matrix == NULL)
                return NULL;
        *matrix = (double *)malloc(rows * cols * sizeof(double));  // 中身を連続して malloc	
        if (*matrix == NULL)
                return NULL;
        for (i = 1; i < rows; i++)
                matrix[i] = *matrix + i * cols;

        return matrix;
}
以下のように使う。
#include "dmatrix.h"

double **matrix;

if ((matrix = dmatrix(nrows, ncols)) == NULL) {
	fprintf(stderr, "cannot allocate matrix\n");
	exit(1);
}
st = myclock();
for (i = 0; i < nrows; i++)
	for (j = 0; j < ncols; j++)
		matrix[i][j] = i + j;
ed = myclock();
ふむふむ, と思っていたが, コードを書いて調べてみると, 下のように 列ごとに malloc する方が速いようだ。えーーーー。;;
コードは上の dmatrix を使った方が綺麗なんだけど..。;
pxn:~/tmp/test% ./mdary 100 100        % 上の dmatrix を使った場合
elapsed =   0.000128
pxn:~/tmp/test% ./mdary2 100 100       % 列ごとに malloc する場合
elapsed =   0.000038
pxn:~/tmp/test% ./mdary 10000 1000
elapsed =   0.158179
pxn:~/tmp/test% ./mdary2 10000 1000
elapsed =   0.128347

1 days displayed.
タイトル一覧
カテゴリ分類
 なかのひと
Powered by hns-2.10-pl1, HyperNikkiSystem Project