• ベストアンサー

プログラムの高速化

要素数Nのfloat型配列aに対して、 Σ(a[i]-a[i-1])^2 を計算するプログラムを高速化したいのですが、 どのような方法がありますか? 今のところ単純に、 答えをanswerとすると for(i = 1; i <= N; i++) answer += (a[i] - a[i-1])*(a[i] - a[i-1]); とする方法しか思いつかないのですが・・・・。

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

本質的には並列計算するしかないでしょう. 場合によっては for (i = 1; i <= N; ++i) { d = a[i]-a[i-1]; answer += d*d; } の方が速いかもしれんけど, この辺は処理系が賢ければ問題ないわけだし. あるいはアセンブラ.

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.2

この程度のプログラムで有れば工夫したところで高が知れています。 データの大きさや個数が大きい時には数値の桁落ちや桁あふれのほうが気になります。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Perlで早いプログラムを作りたい

    perlの初心者です。 一つの配列の構成要素が100~1000のものが1000個ほどあります。 ある配列の一つの要素が他の配列に何個づつあるかを調べています。 作ったプログラムは次の三つですがとても遅く、もっと早い方法があれば 教えてください。 1.foreach $a(@hairetsu1){     $n=0;     foreach $b(@hairetsu2){       $n++ if $a =~ $b;     }   } 2. foreach $a(@hairetsu1){     $n=grep(/$a/,@hairetsu2);  } 3. for($i=0;$i<length(@hairetsu1);$i++){    $n=0;    for($j=0;$j<length(@hairetsu2);$j++)      $n++ if $hairetsu1($i) =~ $hairetsu2($j);    }  } 上が一番早く下に行くほど遅いですがあまり違いはありません。 よろしくお願いします。

  • このプログラムにアドバイスをください

    問題が  ・100個の要素を持った一次元配列をmain()関数内で宣言 ・一次元配列と要素数を引数として持つ関数seisei() ・関数seisei()は乱数を使い渡された配列を0~99の整数で初期化する。 ・一次元配列、要素数そして変数のポインタを引数としてもつ関数goukei() ・関数goukei()は渡された配列に格納された数値の合計を計算し、渡された変数のポインタにその合計値を代入する。 と問題があり、下記のようにプログラムを作ったんですが、どうしてもコンパイルできません。どなたかご指摘よろしくお願いします。 #include <stdio.h> #include <time.h> void seisei(int *,int); void goukei(int *, int, int*); int i, *sum; int main() { int a[100],sum; seisei(a,100); goukei(a,100,&sum); printf("sum:%d\n",&sum); return 0; } void seisei(int *a[i], int n) { srand(time(NULL)); for(i = 0; i <= n; i++){ *a[i] = rand() % 100; } } void goukei(int *a[i],int n,int *sum) { *sum = 0; for(i = 0; i <= n; i++){ *sum += *a[i]; } }

  • Cのプログラムに変換

    どなたかこのプログラムをCに変化してくれる方いませんか? なんで変換するのとかの質問はいらないです。 ただ純粋に変換してくれる方いませんか? #include <stdio.h> #include <stdlib.h> #include <math.h> #include <complex.h> #define NREPEAT 1000 int sweepout(float complex **a, int size) { int n,m,k; // 前進消去 for(n=0; n<size; n++) { // 軸の選択 { float amax = cabs(a[n][n]);; float aabs; int npivot = n; for(m=n+1; m<size; m++) { if((aabs = cabs(a[m][n]))>amax) { npivot = m; amax = aabs; } } if(aabs == 0.0) return n; if(npivot != n) { // 軸の交換 float complex t; for(k=n; k<=size; k++) { t = a[n][k]; a[n][k] = a[npivot][k]; a[npivot][k] = t; } } } // 消去 { float complex t; t = 1.0/a[n][n]; // 対角要素 a[n][n] <-- 1 for(k=n+1; k<=size; k++) a[n][k] *= t; // 非対角要素 a[m][n] <-- 0 for(m=n+1; m<size; m++) { for(k=n+1; k<=size; k++) a[m][k] -= a[m][n]*a[n][k]; } } } // 後退代入 { float t; for(n=size-1; n>0; n--) { for(m=0; m<n; m++) a[m][size] -= a[n][size]*a[m][n]; } } return -1; } // 乱数を発生する double drand() { double rn; rn = (2*((double)random()))/((double)(RAND_MAX))-1.0; return rn; } main(int argc, char **argv) { int n, m, k, ncount; double complex **a0; float complex **a; double complex t; double d, r; if(argc>1) n = atoi(argv[1]); if(n <=0) n = 3; srandom((argc>2)?atoi(argv[2]):0); a0 = (double complex **)malloc(n*sizeof(double complex *)); for(m=0; m<n; m++) a0[m] = (double complex *)malloc((n+1)*sizeof(double complex)); a = (float complex **)malloc(n*sizeof(float complex *)); for(m=0; m<n; m++) a[m] = (float complex *)malloc((n+1)*sizeof(float complex)); for(ncount=0; ncount<NREPEAT; ncount++) { // 乱数により、配列の係数を決める(double型) for(m=0; m<n; m++) for(k=0; k<=n; k++) a0[m][k] = drand() + 1.0I*drand(); // 係数をfloat型に変換し、配列 a に代入する for(m=0; m<n; m++) { for(k=0; k<n; k++) a[m][k] = (float complex)a0[m][k]; t = 0; for(k=0; k<n; k++) t += a0[m][k]*a0[k][n]; a[m][n] = (float complex)t; } // 連立方程式を解き、数値解を a[][n] に求める sweepout(a,n); // 2乗誤差を求める d = r = 0; for(m=0; m<n; m++) { d += pow(cabs(a[m][n]-a0[m][n]),2); r += pow(cabs(a0[m][n]),2); } printf("%lf\t\n", 0.5*log10(d/r)); } for(m=0; m<n; m++) { free(a0[m]); free(a[m]); } free(a0); free(a); }

  • 走査アルゴリズムについて

    n個の要素の配列x[]について 配列xの連続した要素(部分配列)でその和が最大になるものを見つけて、 その和を出力するアルゴリズムについてです。 これなのですが解き方の考え方に 「x[0...n]までの部分配列の最大和は、x[0...n-1]の部分配列の最大和か、x[n]から左方向に伸びた配列の和のいずれかである。」 とあり プログラムには float maxSoFar(float x[], int length){ float maxsofar = 0; float maxendinghere = 0; for(int i = 0; i < length; i++){ maxendinghere = max(0.0f, maxendinghere + x[i]); maxsofar = max(maxsofar, maxendinghere); } return maxsofar; } とあるのですが、アルゴリズムの仕組みがよくわかりません。 なぜ上のような説明でこのようにプログラムできるのかが わからないので、どなたかうまい説明できる人お願いします><

  • C++で分からないプログラムがあるんですが

    ベクトルの加減を行うプログラムを作成せよ。 ベクトルの内積を求めるプログラムを作成せよ。 ↑作るプログラムは1つにする(1つにまとめる) 2つのベクトルを適当に初期化して行う事 これ、だれか教えてくれませんか?配列とforを使うんですが、配列も、1次元と2次元しかやってないですし。 こんな感じのレベルだと思うんですが… #include <iostream> using namespace std; int main() { float w[] = {1.2,2.3,3.4,4.5,5.6}; float x[] = {4.8,2.6,1.3,9.1,8.7}; float u = 0.0; int i; for(i=0;i<5;i=i++) { u += w[i] * x[i]; } cout << "u=" << u << "です\n"; return 0; } 本当に誰か助けてください。

  • 配列を用いて、次のFibonacciの数列{a(n)}n=1,2・・・を計算するプログラムを作りなさい。

    配列を用いて、次のFibonacciの数列{a(n)}n=1,2・・・を計算するプログラムを作りなさい。 a(n+2)=a(n+1)+a(n),a(1)=1,a(2)=1 で、私が作ったプログラムは DIM a(n) INPUT n LET a(1)=1   print 1,a(1) let a(2)=1 print 2,a(2) for i=3 to n let a(i)=a(i-1)+a(i-2) print i,a(i) next i end なのですが、うまくいきません。 どこを改善したらいいかを教えてください。 よろしくおねがいします。

  • C++での、素数の表を作成するプログラムについての質問です。

    C++での、素数の表を作成するプログラムについての質問です。 配列を使用して、2~71までの素数を表に埋め込みたいのです。 プログラム本体はここまで出来ているのですが、 素数を求める計算の方法がイマイチわかりません。 #include<iostream> #include <iomanip> using namespace std; #define N 20 int main() { int arry[N]; /********************************* ここでforを用いた反復で計算を行う **********************************/ /********************* 配列変数の内容を出力 *********************/ for(int i=0;i<N;i++) cout << "+--" ; cout << "+\n" ; for(int i = 0; i < N; i++ ) cout << "|" << setw(2) << arry[i] ; cout << "|\n" ; for(int i = 0; i < N; i++ ) cout << "+--" ; cout << "+\n" ; return 0; } for文を使用した反復構造でarry[N]に2~71までの数字をいれていきたいです。 お願いします。 なお、 int arry[N]={2,3,5,7…} や arry[0]=2; arry[1]=3; arry[2]=5; …のように入力してはいけないのです。

  • 配列の要素に同じ値をもたせないプログラムについて

    現在、JAVAの入門書にてプログラムの勉強中です。 その書籍に掲載のプログラムコードがどうしても意図する結果に なりません。入力間違いなどのミスはないか何回も見直しましたが、 どこも入力間違いは見当たりません。 何が原因か教えて頂けますでしょうか。 実行例がこのようになります。 数字は例なのでこの限りではありません。 要素数 : 7 a[0] = 7 a[1] = 5 a[2] = 1 a[3] = 2 a[4] = 9 a[5] = 6 a[6] = 3 プログラムコードが下記になります。 /*配列の全要素を1から10の乱数で埋め尽くす (すべての要素が重複しないようにする*/ 01: import java.util.Random; 02: import java.util.Scanner; 03: 04: class ArrayRandY { 05: 06: public static void main(String[] args) { 07: Random rand = new Random(); 08: Scanner stdIn = new Scanner(System.in); 09: 10: int n; //要素数 11: do { 12: System.out.print("要素数 : "); 13: n = stdIn.nextInt(); //要素数を読み込む 14: } while (n > 10); 15: int[] a = new int[n]; //配列を生成 16: 17: for (int i = 0; i < n; i++) { 18: int j = 0; 19: do { 20: a[i] = 1 + rand.nextInt(10); 21: for ( ; j < i; j++) 22: if (a[j] == a[i]) break; 23: } while (j < i;); 24: } 25: 26: for (int i = 0; i < n; i++) { 27: System.out.println("a[" + i + "] = " + a[i]); 28: } 29: } 30:} 以上です。 これを javac ArrayRandY.java → java ArrayRandY とやると、重複しない結果のときもありますが 重複する値が出てしまうときもあります。 著者のホームページの正誤表を見たのですが情報がありませんでした。 常にこのプログラムの配列の全要素を重複しないようにするには どうしたらよろしいでしょうか。 よろしくお願いいたします。 ちなみに、プログラムコードですが、入力画面ではインデントを 入力しているのですが確認画面ではなぜかインデントが表現 されてません。 大変見苦しいことお詫び申し上げます。

    • ベストアンサー
    • Java
  • 配列の問題

    配列の問題です。 n個の要素を持つ一次元配列の値(変数値)をまったく逆に入れ替えるプログラムを作りたいのですが、この場合どのようにして逆を表現すればよいのかわかりません。 (nの値は読み込み、配列は奇数個でも偶数個でも使えるプログラムでなければなりません) 参考書を見ながら作ってみたのですが…だめでした。 プログラム初心者です。アドバイスお願いします。 int main(void) { int i,n; int vc[n]; printf("n個の要素を持つ一次元配列をつくる\n"); printf("nの値を入力してください\n"); scanf("%d",&n); for (i=0;i<n+1;i++) vc[i]=i+1; for (i=0;i<5;i++) printf("vc[%d]=%d\n",i,vc[i]); printf("この配列を逆に入れ替えると\n); return 0; }

  • 高速フーリエ変換(FFT)のプログラム

    高速フーリエ変換(FFT)のプログラム 高速フーリエ変換のプログラムが必要になり、visual c++で作成しています。 http://www.kiso.tsukuba.ac.jp/~watanabe/FFT.htm こちらのサイトの一番下のプログラムを参考にして作成しています。 ここで質問なのですが信号データが8点のプログラムが上記のサイトにはあり、私は作成したプログラムが正しいかどうかチェックするため4点の信号データのFFTを求めたいのですが、以下のようにx0=2,x1=2,x3=8,x4=-4の値をフーリエ変換するプログラムにしたところ、この4点フーリエ変換の正規の値と、このプログラムの出力値が違ってしまいます。私の知識不足も否めませんがどこが間違っているのかわからずこまっています。 よろしければ教えてください。 void four1(float datar[],float datai[],unsigned long nn, int isign){ unsigned long n,mmax,m,j,istep,i; double wtemp,wr,wpr,wpi,wi,theta; float tempr,tempi; n=nn; j=0; for (i=0;i<n ;i++) { if (j > i) { SWAP(datar[j], datar[i]); SWAP(datai[j], datai[i]); } m=n >> 1; while (m >= 1 && j > m) { j -= m; m >>= 1; } j += m; } mmax=1; while (n > mmax) { istep=mmax << 1; theta=isign*(6.28318530717959/istep); wtemp=sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi=sin(theta); wr=1.0; wi=0.0; for (m=0;m<mmax;m++) { for (i=m;i<n;i+=istep) { j=i+mmax; tempr=wr*datar[j]-wi*datai[j]; tempi=wr*datai[j]+wi*datar[j]; datar[j]=datar[i]-tempr; datai[j]=datai[i]-tempi; datar[i] += tempr; datai[i] += tempi; } wr=(wtemp=wr)*wpr-wi*wpi+wr; wi=wi*wpr+wtemp*wpi+wi; } mmax=istep; } } void realft() { float datar[4]={2.0,2.0,8.0,-4.0}; float datai[4]={0.0,0.0,0.0,0.0}; int i; four1(datar,datai,4,-1); for(i=-1;i<3;i++){ printf("i = %d:\tReal: %f, \tImag: %f\n", i, datar[i]/4,datai[i]/4); } }