R Space interpolation 空間補間 ソースコード編集2

C言語の勉強も進んだので、目的である空間補間のソースコード編集をやってみたい。このサイトが非常に分かりやすいので参考にした。

エラーが起きた理由の振り返り

こちらでRの空間補間パッケージを使用した際、エラーが起きた。コードの意味も含め、おさらいをする。まず、エラーは

> P.dat.krige <- krige(Intensity~1, P.dat, dat.grid, model = P.m)
[using ordinary kriging]

"memory.c", line 58: can't allocate memory in function m_get()
predict.gstat(g, newdata = newdata, block = block, nsim = nsim,:m_get

ココからgstatを直接ダウンロードし、memory.cをviモードで開いてみる。問題となっているのはline58であり、

#ifndef SEGMENTED //SEGMENTEDが定義されていないときのみコンパイルされる、という意味。
   if {(matrix->base = NEW_A(m*n,Real)) == (Real *)NULL} //この条件を満たせばエラーとなる。※文字化け対策で()を{}にしています
   {
      free(matrix);
      error(E_MEM,"m_get");    //ココでエラーらしい。
   }
   else if (mem_info_is_on()) {
      mem_bytes(TYPE_MAT,0,m*n*sizeof(Real));
   }
#else
   matrix->base = (Real *)NULL;
#endif

の if {(matrix->base = NEW_A(m*n,Real)) == (Real *)NULL} 部分の条件を満たしたが故にエラーとなったのであった。memory.cの冒頭には

/* memory.c 1.3 11/25/87 */
#include        "matrix.h"

と表記してあるため、matrix.hを開いてみると、NEW_Aに関して定義が記載されている。

/* allocate num objects of given type */
#define NEW_A(num,type) ((type *)calloc((unsigned)(num),sizeof(type)))

こちらにも定義があるように、calloc関数は「指定バイト分メモリ領域をn個分確保する関数」であり、第1引数はメモリブロックの個数、第2引数は確保したいメモリのバイトサイズを表す。

コードの修正をしてみたが…

おそらくNEW_A(m*n,Real)でメモリの確保失敗したものと思われる。memory.cではm,nはint型で指定されていた。

/* m_get -- gets an mxn matrix (in MAT form) by dynamic memory allocation */
MAT     *m_get(m,n)
int m,n;

 int型の変域は-2147483648~2147483648であるのに対し、今回解析するデータはn=1626300,m=1626300であった。したがって、n*mはint型の変域を逸脱することになる。そこで、型を変えて

long long m,n;

 と修正し、再度この手順でパッケージをインストールしてみた。しかし、エラーの表示は変わらない。また考えることにする。