• ベストアンサー

シグマの計算

シグマの計算が良く分からなくなってしまいました。。 p = Σ(x_i*x_i+k) (k=1~10)で、Σは(i=1~n-k)です。(見難くてすみません…) それで、nを2000000として計算したいので、全部は配列などに入れられないので、 x_iを10個ずつ配列に入れながら足していきたいのですが… どうすれば出来るか、紙に色々書いたりしているのですが考えつきません(>_<) どなたかヒントや考え方を教えてください!! お願いしますm(__)m

質問者が選んだベストアンサー

  • ベストアンサー
noname#30727
noname#30727
回答No.4

なるほど。乱数をk個保存しておく必要があるのですね。 ベタに書きますが、例えば、k が 5 だとして、k + 1 要素の配列 buff があるとします。 buff[5] = buff[4]; buff[4] = buff[3]; buff[3] = buff[2]; buff[2] = buff[1]; buff[1] = buff[0]; buff[0] = 次の乱数(); このように配列の中身を1つぶんずらしながら次の乱数を取得していけば、「常に」今取得した乱数は buff[0] に、5つ前の乱数は buff[5] にある事になります。 ただし、最初の5回は5つ前の値が無いので、最初だけ乱数を6回取得する必要があります。 memmoveを使用すれば、ベタに書かずにずらせます。 配列が大きい場合にはリングバッファの方が効率が良いですが、気になったら調べてみて下さい。C++ なら std::deque を使います。

apple_cube
質問者

お礼

ありがとうございます! inthefloiさんの考え方は分かったのですが、 なかなかプログラムとして書けません(^_^;) for(j=0 ; j<10 ; j++){ x0 = random_g(x0, a, c); tmp = x0 / (double)4294967296; late[j] = tmp; } for(k=1 ; k<=10 ; k++){ for(i=1 ; i<=n-k ; i++){ for(j=9; 0<j ; j--){ late[j] = late[j-1]; } x0 = random_g(x0, a, c); tmp = x0 / (double)4294967296; late[0] = tmp; sigpk += late[i]*late[i+k]; printf("%f\n", sigpk); } }

その他の回答 (7)

noname#30727
noname#30727
回答No.8

>自分のプログラムでmallocを使うとエラー?になってしまいました。 「エラー?」ではわかりません。横着せずに「正確」に書いて下さい。 コンパイルエラーが出て自分で対処できないという事であれば、そのエラーメッセージを張り付けるくらいの事はするものです。 関数や変数の宣言部分もいいかげん省略したままですが、出せる情報をすべて出すのが、人に協力を求める時の基本です。 >x = (double *)malloc(sizeof(double) * N); これでコンパイルエラーが出るとしたら、x が double * 型ではないか、mallocを呼び出すための stdlib.hがインクルードされていないか、N が不正な値であるかのどれかです。 stdlib.h は malloc.h でもかまいません。 >コンパイラはBorland C++5.5を使っています。LSI C86でもエラーが出ました。 コンパイラはBorland C++5.5で問題ないです。 LSI C86は16bitコンパイラなので、この場合は役者不足です。

apple_cube
質問者

補足

コンパイルエラーではないので、何も書けませんでした。 コンパイルは出来ますが実行するとエラーになります。 プログラムですが、下の方で判定しているのは課題なのであまり気にしないで下さい(^-^;) #include<stdio.h> #include<math.h> #include<stdlib.h> #define N 200000 int main(void) { unsigned long mkrandom(unsigned long a, unsigned long c, unsigned long x0); double p[10], t, sigpk, *x; unsigned long a, c, x0; int i, k; x = (double *)malloc(sizeof(double) * N); if(x == NULL){ printf("mallocに失敗\n"); return -1; } for(i=0 ; i<N ; i++){ x[i]=0.0; } /* printf("x0: "); scanf("%d", x); printf("a: "); scanf("%d", &a); printf("c: "); scanf("%d", &c); */ x[0] = 1; a = 61; c = 49; x0 = x[0]; for(i=2 ; i<=N ; i++){ x0 = mkrandom(a, c, x0); x[i-2] = x0 / (double) 4294967296; /*printf("x[] = %f\n", x[i-2]);*/ } for(k = 1; k <= 10; k++){ p[k-1] = 0.0; sigpk = 0.0; for(i=1; i<=N-k ; i++){ sigpk += (double)x[i-2]*x[i-2 +k]; p[k-1] = 12.0/N*sigpk - 3; } } for(k = 1; k <= 10; k++){ t = sqrt(N-2)*p[k-1]/sqrt(1 - pow(p[k-1], 2)); printf("P_%d = %f, t = %f", k, p[k-1], t); if(t < 2.326){ printf(" --> 受容"); } else{ printf(" --> 棄却"); } printf("\n"); } free(x); return 0; } unsigned long mkrandom(unsigned long a, unsigned long c, unsigned long x0){ return a*x0 + c; }

noname#30727
noname#30727
回答No.7

ANo.6です。 >そうなんですが、乱数列を発生させて配列にXiを入れつつΣ(相関係数)を計算していくのが分かりません(>_<) そんなバカげた事を言われても、それは質問者さんの課題ですとしか言えません。 >なので、配列を2000000こ分でやってみようかと思いましたが、 >20000までしかできませんでした(^_^;) この配列の型がdoubleだとしても、必要なメモリは16MB程度なので、使えない事もないと思います。OSとコンパイラは何を使用していますか? あと、配列の確保の仕方が気になります。ある程度より大きなメモリはmallocやnewでしか確保できない事があります。 #include <stdio.h> #include <stdlib.h> #define N 2000000 typedef double x_type; int main() { x_type *x; int i; x = (double*)malloc(sizeof(x_type) * N); if (x == NULL) { printf("mallocに失敗\n"); return -1; } for (i = 0; i < N; i++) { x[i] = 0.0; } printf("mallocと初期化に成功\n"); free(x); return 0; } これを実行できれば解決ですね。

apple_cube
質問者

お礼

inthefloiさんが書かれたプログラムでは成功しましたが、 自分のプログラムでmallocを使うとエラー?になってしまいました。 OSはWindowsXPで、コンパイラはBorland C++5.5を使っています。LSI C86でもエラーが出ました。 ちなみに、下のようにしました・・・・ x = (double *)malloc(sizeof(double) * N); if(x == NULL){ printf("mallocに失敗\n"); return -1; } for(i=0 ; i<N ; i++){ x[i]=0.0; } x[0] = 1; a = 61; c = 49; x0 = x[0]; for(i=2 ; i<=N ; i++){ x0 = mkrandom(a, c, x0); x[i-2] = x0 / (double) 4294967296; /*printf("x[] = %f\n", x[i-2]);*/ } for(k = 1; k <= 10; k++){ p[k-1] = 0.0; sigpk = 0.0; for(i=1; i<=N-k ; i++){ sigpk += (double)x[i-2]*x[i-2 +k]; p[k-1] = 12.0/N*sigpk - 3; } }

noname#30727
noname#30727
回答No.6

ANo.4です。 >sigpk += late[i]*late[i+k]; まず sigp[k] を求めて、その後に相関係数を出すという課題ではないのですか? 回答者は超能力者ではないので、わからないと言われても、何がわからないのかわかりませんよ。

apple_cube
質問者

補足

そうなんですが、乱数列を発生させて配列にXiを入れつつΣ(相関係数)を計算していくのが分かりません(>_<) なので、配列を2000000こ分でやってみようかと思いましたが、 20000までしかできませんでした(^_^;) for(k = 1; k <= 10; k++){ p[k-1] = 0.0; sigpk = 0.0; for(i=1; i<=N-k ; i++) sigpk += (double)x[i-2]*x[i-2 +k]; p[k-1] = 12.0/N*sigpk - 3; }

  • Interest
  • ベストアンサー率31% (207/659)
回答No.5

要素数がn個の乱数列はどのように与えられるのでしょうか。 自分でプログラム中で生成してOK? それともファイルか標準入力あたりからもらってくるのでしょうか? 仮にファイルだとすれば、 sum = 0; for(i=1; i<n-k; i++){  xi = ReadFromFile(i);  xj = ReadFromFile(i+k);  sum += xi * xj; // Σ(x_i*x_i+k) } こんなんで和が求まりますね。 (ReadFromFileは与えられるデータファイルがカンマ区切りかタブ区切りかにあわせて、適当な関数を作って補ってください。)

apple_cube
質問者

お礼

乱数列は線形合同法で生成します。 関数を使ってるんですが、forが多くなってしまってよくわからない状態です(^_^;)

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.3

x_i がわからないと計算できませんが、iが決まればXiがきまるんですか? だったら式を示してください。 それとも、ファイルに入ってるのでしょうか? なお、n=2000000だったら、いまどきのコンピュータなら配列に入りますよ。 配列に入れるのが正しい計算方法だとは思えませんが。

apple_cube
質問者

補足

これは問題の一部だったのですが、xは乱数列です。 n個の乱数列x_1…x_nが与えられて、 k個ずらした数の組 (x_1, x_1+k), (x_2, x_2+k)…(x_n-k, x_n) から計算されるそうかん係数を求めたかったんです。。 わかりにくくてすみません(^_^;)

noname#30727
noname#30727
回答No.2

なぜ配列に入れる必要があるのでしょうか。 p = 0; としてから、pに足していくだけではダメなのですか? intでは足りないというのならわかるのですが。

apple_cube
質問者

補足

必要、というか配列が10こくらいないと無理かなと考えたので…。

回答No.1

言語が何にせよプログラムを書くならfor/while等のループは基本です

apple_cube
質問者

補足

すみません。 それは思いついたんですが、条件やどこで分ければいいかなどですごく迷ってしまいました・・・

関連するQ&A

専門家に質問してみよう