MATLAB Answers

0

関数chi2invのC言語における動作

Asked by Yuki Fukuda on 17 May 2018
Latest activity Commented on by michio
on 19 May 2018

C言語でカイ2乗検定をしたく,関数chi2invをC言語に変換し,ディレクトリ最上部の全てのCファイルとhファイルを実装して動作させてみたところ,自由度2と4における逆関数の値がそれぞれの場合で全て2.0000と4.0000となってしまいます.これは仕様でしょうか?

以下に実際に利用したコードを記します.

#include <stdio.h>
#include "./CHIINV/include.h" //生成した全てのヘッダファイル,cファイルをまとめたヘッダファイル
int main(void){
   int k = 0; //ループ用ならびに自由度
   double alpha = 0.0; //ループ用ならびに有意水準
     //自由度30まで
     for(k = 1; k <= 30; k++){
          //有意水準0.05まで
          for(alpha = 0.01; alpha <= 0.05; alpha += 0.01){
               //カイ2乗分布表の数値を出力
               printf("chi2(%.2f, %d) = %.3f\n", 1.0-alpha, k, CHIINV(1.0-alpha, (double)k));
               //先程の型付けに関する注意点.ここではint型変数kをdouble型にキャストして代入
          }
     }
     return 0;
}

また,実行結果は以下の通りです.

./testCHIINV
chi2(0.99, 1) = 6.635
chi2(0.98, 1) = 5.412
chi2(0.97, 1) = 4.709
chi2(0.96, 1) = 4.218
chi2(0.95, 1) = 3.841
chi2(0.99, 2) = 2.000
chi2(0.98, 2) = 2.000
chi2(0.97, 2) = 2.000
chi2(0.96, 2) = 2.000
chi2(0.95, 2) = 2.000
chi2(0.99, 3) = 11.345
chi2(0.98, 3) = 9.837
chi2(0.97, 3) = 8.947
chi2(0.96, 3) = 8.311
chi2(0.95, 3) = 7.815
chi2(0.99, 4) = 4.000
chi2(0.98, 4) = 4.000
chi2(0.97, 4) = 4.000
chi2(0.96, 4) = 4.000
chi2(0.95, 4) = 4.000
chi2(0.99, 5) = 15.086
chi2(0.98, 5) = 13.388
chi2(0.97, 5) = 12.375
chi2(0.96, 5) = 11.644
chi2(0.95, 5) = 11.070
chi2(0.99, 6) = 16.812
chi2(0.98, 6) = 15.033
chi2(0.97, 6) = 13.968
chi2(0.96, 6) = 13.198
chi2(0.95, 6) = 12.592
chi2(0.99, 7) = 18.475
chi2(0.98, 7) = 16.622
chi2(0.97, 7) = 15.509
chi2(0.96, 7) = 14.703
chi2(0.95, 7) = 14.067
chi2(0.99, 8) = 20.090
chi2(0.98, 8) = 18.168
chi2(0.97, 8) = 17.010
chi2(0.96, 8) = 16.171
chi2(0.95, 8) = 15.507
chi2(0.99, 9) = 21.666
chi2(0.98, 9) = 19.679
chi2(0.97, 9) = 18.480
chi2(0.96, 9) = 17.608
chi2(0.95, 9) = 16.919
chi2(0.99, 10) = 23.209
chi2(0.98, 10) = 21.161
chi2(0.97, 10) = 19.922
chi2(0.96, 10) = 19.021
chi2(0.95, 10) = 18.307
chi2(0.99, 11) = 24.725
chi2(0.98, 11) = 22.618
chi2(0.97, 11) = 21.342
chi2(0.96, 11) = 20.412
chi2(0.95, 11) = 19.675
chi2(0.99, 12) = 26.217
chi2(0.98, 12) = 24.054
chi2(0.97, 12) = 22.742
chi2(0.96, 12) = 21.785
chi2(0.95, 12) = 21.026
chi2(0.99, 13) = 27.688
chi2(0.98, 13) = 25.472
chi2(0.97, 13) = 24.125
chi2(0.96, 13) = 23.142
chi2(0.95, 13) = 22.362
chi2(0.99, 14) = 29.141
chi2(0.98, 14) = 26.873
chi2(0.97, 14) = 25.493
chi2(0.96, 14) = 24.485
chi2(0.95, 14) = 23.685
chi2(0.99, 15) = 30.578
chi2(0.98, 15) = 28.259
chi2(0.97, 15) = 26.848
chi2(0.96, 15) = 25.816
chi2(0.95, 15) = 24.996
chi2(0.99, 16) = 32.000
chi2(0.98, 16) = 29.633
chi2(0.97, 16) = 28.191
chi2(0.96, 16) = 27.136
chi2(0.95, 16) = 26.296
chi2(0.99, 17) = 33.409
chi2(0.98, 17) = 30.995
chi2(0.97, 17) = 29.523
chi2(0.96, 17) = 28.445
chi2(0.95, 17) = 27.587
chi2(0.99, 18) = 34.805
chi2(0.98, 18) = 32.346
chi2(0.97, 18) = 30.845
chi2(0.96, 18) = 29.745
chi2(0.95, 18) = 28.869
chi2(0.99, 19) = 36.191
chi2(0.98, 19) = 33.687
chi2(0.97, 19) = 32.158
chi2(0.96, 19) = 31.037
chi2(0.95, 19) = 30.144
chi2(0.99, 20) = 37.566
chi2(0.98, 20) = 35.020
chi2(0.97, 20) = 33.462
chi2(0.96, 20) = 32.321
chi2(0.95, 20) = 31.410
chi2(0.99, 21) = 38.932
chi2(0.98, 21) = 36.343
chi2(0.97, 21) = 34.759
chi2(0.96, 21) = 33.597
chi2(0.95, 21) = 32.671
chi2(0.99, 22) = 40.289
chi2(0.98, 22) = 37.659
chi2(0.97, 22) = 36.049
chi2(0.96, 22) = 34.867
chi2(0.95, 22) = 33.924
chi2(0.99, 23) = 41.638
chi2(0.98, 23) = 38.968
chi2(0.97, 23) = 37.332
chi2(0.96, 23) = 36.131
chi2(0.95, 23) = 35.172
chi2(0.99, 24) = 42.980
chi2(0.98, 24) = 40.270
chi2(0.97, 24) = 38.609
chi2(0.96, 24) = 37.389
chi2(0.95, 24) = 36.415
chi2(0.99, 25) = 44.314
chi2(0.98, 25) = 41.566
chi2(0.97, 25) = 39.880
chi2(0.96, 25) = 38.642
chi2(0.95, 25) = 37.652
chi2(0.99, 26) = 45.642
chi2(0.98, 26) = 42.856
chi2(0.97, 26) = 41.146
chi2(0.96, 26) = 39.889
chi2(0.95, 26) = 38.885
chi2(0.99, 27) = 46.963
chi2(0.98, 27) = 44.140
chi2(0.97, 27) = 42.407
chi2(0.96, 27) = 41.132
chi2(0.95, 27) = 40.113
chi2(0.99, 28) = 48.278
chi2(0.98, 28) = 45.419
chi2(0.97, 28) = 43.662
chi2(0.96, 28) = 42.370
chi2(0.95, 28) = 41.337
chi2(0.99, 29) = 49.588
chi2(0.98, 29) = 46.693
chi2(0.97, 29) = 44.913
chi2(0.96, 29) = 43.604
chi2(0.95, 29) = 42.557
chi2(0.99, 30) = 50.892
chi2(0.98, 30) = 47.962
chi2(0.97, 30) = 46.160
chi2(0.96, 30) = 44.834
chi2(0.95, 30) = 43.773

ちなみに,include.hの中は以下の通りです.

#include "CHIINV.c"
#include "CHIINV.h"
#include "CHIINV_initialize.c"
#include "CHIINV_initialize.h"
#include "CHIINV_terminate.c"
#include "CHIINV_terminate.h"
#include "CHIINV_types.h"
#include "gammaln.h"
#include "gammaln.c"
#include "gammaincinv.c"
#include "gammaincinv.h"
#include "rtGetNaN.h"
#include "rtGetNaN.c"
#include "rt_nonfinite.c"
#include "rt_nonfinite.h"
#include "rtGetInf.c"
#include "rtGetInf.h"
#include "rtwtypes.h"

よろしくお願いいたします.

  2 Comments

michio
on 17 May 2018

生成されたCコードの検証方法として、MEX関数を生成し元の MATLAB 関数と同じ結果を返すかどうかを確認するのも1つ方法でお勧めです。

MATLAB Coder アプリでの MEX 関数の検証

ちなみに使用された MATLAB のバージョンはいくつでしょうか?

MEXファイルそのものをMATLABで実行してみましたが,正しい値が出力されております.Cソースコードを出力してC言語プログラムに移植した際にこの問題が発生するようです.

使用したMATLABのバージョンはR2016b(Linux)とR2017b(Windows)です.どちらもGCC(MinGW)からビルドしていますが,同様の問題が発生します.

Sign in to comment.

Products


Release

R2016b

1 Answer

michio
Answer by michio
on 18 May 2018

CHIINV 関数を実行する前(for ループの前)に、生成された関数の1つ

CHIINV_initialize();

を一度だけ実行してみてください。

  2 Comments

実行したところ、以下のように、分布表通りの正しい出力が得られました。ありがとうございます。

chi2(0.99, 1) = 6.635
chi2(0.98, 1) = 5.412
chi2(0.97, 1) = 4.709
chi2(0.96, 1) = 4.218
chi2(0.95, 1) = 3.841
chi2(0.99, 2) = 9.210
chi2(0.98, 2) = 7.824
chi2(0.97, 2) = 7.013
chi2(0.96, 2) = 6.438
chi2(0.95, 2) = 5.991
chi2(0.99, 3) = 11.345
chi2(0.98, 3) = 9.837
chi2(0.97, 3) = 8.947
chi2(0.96, 3) = 8.311
chi2(0.95, 3) = 7.815
chi2(0.99, 4) = 13.277
chi2(0.98, 4) = 11.668
chi2(0.97, 4) = 10.712
chi2(0.96, 4) = 10.026
chi2(0.95, 4) = 9.488
chi2(0.99, 5) = 15.086
chi2(0.98, 5) = 13.388
chi2(0.97, 5) = 12.375
chi2(0.96, 5) = 11.644
chi2(0.95, 5) = 11.070
chi2(0.99, 6) = 16.812
chi2(0.98, 6) = 15.033
chi2(0.97, 6) = 13.968
chi2(0.96, 6) = 13.198
chi2(0.95, 6) = 12.592
chi2(0.99, 7) = 18.475
chi2(0.98, 7) = 16.622
chi2(0.97, 7) = 15.509
chi2(0.96, 7) = 14.703
chi2(0.95, 7) = 14.067
chi2(0.99, 8) = 20.090
chi2(0.98, 8) = 18.168
chi2(0.97, 8) = 17.010
chi2(0.96, 8) = 16.171
chi2(0.95, 8) = 15.507
chi2(0.99, 9) = 21.666
chi2(0.98, 9) = 19.679
chi2(0.97, 9) = 18.480
chi2(0.96, 9) = 17.608
chi2(0.95, 9) = 16.919
chi2(0.99, 10) = 23.209
chi2(0.98, 10) = 21.161
chi2(0.97, 10) = 19.922
chi2(0.96, 10) = 19.021
chi2(0.95, 10) = 18.307
chi2(0.99, 11) = 24.725
chi2(0.98, 11) = 22.618
chi2(0.97, 11) = 21.342
chi2(0.96, 11) = 20.412
chi2(0.95, 11) = 19.675
chi2(0.99, 12) = 26.217
chi2(0.98, 12) = 24.054
chi2(0.97, 12) = 22.742
chi2(0.96, 12) = 21.785
chi2(0.95, 12) = 21.026
chi2(0.99, 13) = 27.688
chi2(0.98, 13) = 25.472
chi2(0.97, 13) = 24.125
chi2(0.96, 13) = 23.142
chi2(0.95, 13) = 22.362
chi2(0.99, 14) = 29.141
chi2(0.98, 14) = 26.873
chi2(0.97, 14) = 25.493
chi2(0.96, 14) = 24.485
chi2(0.95, 14) = 23.685
chi2(0.99, 15) = 30.578
chi2(0.98, 15) = 28.259
chi2(0.97, 15) = 26.848
chi2(0.96, 15) = 25.816
chi2(0.95, 15) = 24.996
chi2(0.99, 16) = 32.000
chi2(0.98, 16) = 29.633
chi2(0.97, 16) = 28.191
chi2(0.96, 16) = 27.136
chi2(0.95, 16) = 26.296
chi2(0.99, 17) = 33.409
chi2(0.98, 17) = 30.995
chi2(0.97, 17) = 29.523
chi2(0.96, 17) = 28.445
chi2(0.95, 17) = 27.587
chi2(0.99, 18) = 34.805
chi2(0.98, 18) = 32.346
chi2(0.97, 18) = 30.845
chi2(0.96, 18) = 29.745
chi2(0.95, 18) = 28.869
chi2(0.99, 19) = 36.191
chi2(0.98, 19) = 33.687
chi2(0.97, 19) = 32.158
chi2(0.96, 19) = 31.037
chi2(0.95, 19) = 30.144
chi2(0.99, 20) = 37.566
chi2(0.98, 20) = 35.020
chi2(0.97, 20) = 33.462
chi2(0.96, 20) = 32.321
chi2(0.95, 20) = 31.410
chi2(0.99, 21) = 38.932
chi2(0.98, 21) = 36.343
chi2(0.97, 21) = 34.759
chi2(0.96, 21) = 33.597
chi2(0.95, 21) = 32.671
chi2(0.99, 22) = 40.289
chi2(0.98, 22) = 37.659
chi2(0.97, 22) = 36.049
chi2(0.96, 22) = 34.867
chi2(0.95, 22) = 33.924
chi2(0.99, 23) = 41.638
chi2(0.98, 23) = 38.968
chi2(0.97, 23) = 37.332
chi2(0.96, 23) = 36.131
chi2(0.95, 23) = 35.172
chi2(0.99, 24) = 42.980
chi2(0.98, 24) = 40.270
chi2(0.97, 24) = 38.609
chi2(0.96, 24) = 37.389
chi2(0.95, 24) = 36.415
chi2(0.99, 25) = 44.314
chi2(0.98, 25) = 41.566
chi2(0.97, 25) = 39.880
chi2(0.96, 25) = 38.642
chi2(0.95, 25) = 37.652
chi2(0.99, 26) = 45.642
chi2(0.98, 26) = 42.856
chi2(0.97, 26) = 41.146
chi2(0.96, 26) = 39.889
chi2(0.95, 26) = 38.885
chi2(0.99, 27) = 46.963
chi2(0.98, 27) = 44.140
chi2(0.97, 27) = 42.407
chi2(0.96, 27) = 41.132
chi2(0.95, 27) = 40.113
chi2(0.99, 28) = 48.278
chi2(0.98, 28) = 45.419
chi2(0.97, 28) = 43.662
chi2(0.96, 28) = 42.370
chi2(0.95, 28) = 41.337
chi2(0.99, 29) = 49.588
chi2(0.98, 29) = 46.693
chi2(0.97, 29) = 44.913
chi2(0.96, 29) = 43.604
chi2(0.95, 29) = 42.557
chi2(0.99, 30) = 50.892
chi2(0.98, 30) = 47.962
chi2(0.97, 30) = 46.160
chi2(0.96, 30) = 44.834
chi2(0.95, 30) = 43.773

CHIINV_initialize();は何を行う関数でしょうか?

ついでにですが、今回のように、要求の関数を実行する前に実行が必要な関数を見分ける方法について教えていただけますと幸いです。

michio
on 19 May 2018

勉強不足で詳細に理解できていないのですが、CHIINV の計算に必要なデータ型の定義を行っているようです。CHIINV_terminate()は空で、何も処理していません。

今回のケースですと、コード生成時に生成された example フォルダ下に実際の呼び出し方例(main.c/main.h)がありますので、こちらを参考にしました。

Sign in to comment.