0

C++ でライブラリ GSL から関数 gsl_histogram_pdf_sample を使用する方法を理解するのに問題があります。ドキュメントはこちら、

http://www.gnu.org/software/gsl/manual/html_node/The-histogram-probability-distribution-struct.html#The-histogram-probability-distribution-struct

私はまだ専門家ではないので、このコードの何が問題なのか誰か教えてもらえないかと思っていましたが、

#include <iostream>
#include <gsl/gsl_histogram.h>
#include <gsl/gsl_rng.h>

using namespace std;

int main()
{
    // I am going to use 5 bins
    size_t  Bins = 5;
    // These are the ranges (must be Bins + 1)
    double range[6] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
    // Array with probabilities
    double w[5]  = {0.05, 0.1, 0.3, 0.4, 1};

    // Create the histogram pdf

    gsl_histogram_pdf MyHistPdf;

    MyHistPdf.n     = Bins;
    MyHistPdf.range = range;
    MyHistPdf.sum   = w;

    const gsl_rng_type * T;
    gsl_rng * r;
    T = gsl_rng_default;
    r = gsl_rng_alloc (T);
    double u = gsl_rng_uniform(r);
    cout << u << endl;
    double a = gsl_histogram_pdf_sample(&MyHistPdf, u);

    return 0;
}

プログラムはエラーなしでコンパイルされますが、実行すると常に次のエラーが発生します。

gsl: /usr/src/gsl-1.16-1/src/gsl-1.16/histogram/pdf.c:46: ERROR: cannot find r in cumulative pdf

そして、私はそれが何を意味するのか分かりません。

4

1 に答える 1

1

あなたの質問に答える前に、GSL に関する基本的なルールを理解する必要があります。それを行うと、プログラムは必然的に失敗するか、結果が意味をなさないでしょう! なんで?これらの変数がどのように格納され、操作されるかについての内部 gsl 規則を詳しく知らないからです!

ドキュメントを注意深く読むと、すべての構造体変数を割り当てて操作するための API 関数があることがわかります。あなたが C++ コーダーである場合、GSL 構造体のすべての変数がプライベートであると想像するのが適切な「経験則」です (これが当てはまらない唯一の理由は、C にはメンバー変数をプライベートにする機能がないためです!)。

ドキュメントでは、gsl_histogram_pdf_sample を呼び出す前に、gsl_histogram 構造体を割り当てる必要があること、いくつかのデータを挿入する必要があること、および使用する gsl_histogram_pdf を特定の API 関数を使用して初期化する必要があることは明らかです。「sum」ポインターをハッキングしてデータの挿入を回避しようとして、GSL が失敗したのを見ました。これは、基本的なルールに従わない場合に発生すると言ったとおりです。

これは私があなたを導くために書いた例です

#include <iostream>
#include <cassert>
#include <gsl/gsl_histogram.h>
#include <gsl/gsl_rng.h>

using namespace std;

int main()
{
   size_t  Bins = 5;
   double range[6] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };

    // histogram 
    gsl_histogram* hist = gsl_histogram_alloc (Bins);
    assert( hist != NULL );
    gsl_histogram_set_ranges (hist, range, 6);

    // include some elements
    const gsl_rng_type * T = gsl_rng_default;
    gsl_rng *r = gsl_rng_alloc (T);

    for(int j = 0; j < 10000; ++j ) {
      const double u = gsl_rng_uniform(r) * 5.0; 
      gsl_histogram_increment (hist, u);            
    }

    // Create the histogram pdf
    gsl_histogram_pdf*  MyHistPdf = gsl_histogram_pdf_alloc (Bins);
    assert( MyHistPdf != NULL );
    int status = gsl_histogram_pdf_init (MyHistPdf, hist);
    assert( status != GSL_EDOM );

    std::cout << "result you want";
    std::cout << gsl_histogram_pdf_sample(MyHistPdf,gsl_rng_uniform(r)) << std::endl;           
    return 0;
  }
于 2013-08-28T05:30:40.607 に答える