掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.25185

離散コサイン変換とそのファイル出力
投稿者---HIDE(2006/01/10 03:34:00)


みなさん初めまして。
かなりの初心者なのですが、学校の課題で離散コサイン変換の課題を出され、
なんとか以下まではたどり着いているのですが、どうにも結果がファイルにうまく出力できません。

どうかお知恵を拝借できればと思い投稿します。

環境は
WinXP home SP2
Visual Studio.NETの
Microsoft Visual C++ .NET 69504-270-0000007-18217
です。

プログラム
-----------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    double x[10000];                            /*元の値を入れる変数*/
    double wa;                  /*和の変数*/
    double sekiwa;                /*積和の変数*/
    double sekiwa0;        /*mが0の時の積和の変数*/
    double r[100],db,suma
    int i,m,n,l,a;
    FILE *fp1,*fp2;        /*入力ファイル用、出力ファイル用*/

    fp1=fopen("SLEEP.txt","r");     /*fp1にSLEEPからファイルを読み込む*/
    fp2=fopen("Kbunsan.txt","w");            /*fp2からKbunsanにファイルを書き込む*/
    
    if(fp1==NULL){                /*ファイルが読み込めない場合エラーメッセージを表示*/
    printf("ファイルが開けません。\n");
    exit(1);
    }
    
    while(1){                           /*ファイルの終わりにEOFが出てくるまでデータを読み込む*/
    if(fscanf(fp1,"%f",&x[i])==EOF){break;}
    i++;
    }
    
    n=i;

    wa=0;                              /*和の変数を0にする*/
    
    for(i=0;i<n;i++){ 
    wa=wa+x[i];         /*配列の変数の和を計算する*/
    }

    wa=wa/n;                                    /*平均を計算する*/
    
    for(i=0;i<n;i++){ 
    x[i]=x[i]-wa;                        /*元の変数からデータから求めた平均値を引く*/
    }
    
    for(m=0;m<n;m++){
        wa=0;                           /*和の変数を0にする*/
        for(i=0;i<n-m;i++){ 
            wa=wa+x[i]*x[i+m];          /*積和を求める*/
        }
        sekiwa=wa/(n-m);                        /*共分散を求める*/
        if(m==0){                        /*m=0の時のみ共分散R(0)を記憶する*/
            sekiwa0=sekiwa;
        }
        fprintf(fp2,"%f %f %f\n",t*m,sekiwa,sekiwa/sekiwa0);
    }                                 /*求めた計算結果を表示する*/
    
    for(n=1;n<=50;n++){       /*離散コサイン変換する*/
        suma=0;
        for(l=0;l<=100;l++){
            a=r[l]*cos(2.0*3.141592*n/100.0*l);
            suma=a+suma
        }
    dB=10*log10(suma/101);
    fprintf(fp2,"%f \n",dB);                    /*結果をファイルfp2に書き込む*/
    }

    fclose(fp1);
    fclose(fp2);                                /*fp1,fp2のファイルを閉じる*/
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> 補足 25186 HIDE 2006/01/10 03:57:00
<子記事> Re:離散コサイン変換とそのファイル出力 25191 nop 2006/01/10 11:17:26
<子記事> Re:離散コサイン変換とそのファイル出力 25192 wiz 2006/01/10 11:31:28


No.25186

補足
投稿者---HIDE(2006/01/10 03:57:00)


書き忘れましたので補足します。

SLEEP.txtの中身は睡眠中の心拍の変化が記されており、

88
88
86
79
81
81
88
90
76
71
69
73
72



と延々記されています。

離散コサイン変換時に100程度しか値を使用していないのは、
共分散の傾向が100程度でつかめるからです。

ただ、どの時点で100程度に絞ればよいのか分からず、前段階は
全ての値を使用しています。
もっとよい方法があればご教授ください。

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


この投稿にコメントする

削除パスワード

No.25191

Re:離散コサイン変換とそのファイル出力
投稿者---nop(2006/01/10 11:17:26)


>なんとか以下まではたどり着いているのですが、どうにも結果がファイルにうまく出力できません。

【掲示板利用宣言】より
# 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。

環境は書かれていますが、
症状が具体的に書かれいません。

・どうの様にうまくいかないのか?
・本来であれば、どの様になるべきなのか?

を明確に書かなければ、誰も回答できません。


この投稿にコメントする

削除パスワード

No.25192

Re:離散コサイン変換とそのファイル出力
投稿者---wiz(2006/01/10 11:31:28)


久々にきちんと字下げされたコードですが、
投稿する時にはせめてコンパイルできる状態でお願いしますね。。。
実行できたということは元のコードがあるはずですが。。。

double r[100],db,suma
;がありません

fprintf(fp2,"%f %f %f\n",t*m,sekiwa,sekiwa/sekiwa0);
tってなに?

suma=a+suma
;がありません

dB=10*log10(suma/101);
dBってなに?



この投稿にコメントする

削除パスワード

No.25195

Re:離散コサイン変換とそのファイル出力
投稿者---HIDE(2006/01/10 13:10:47)


さっそくのレスありがとうございます。

>nop様
失礼しました。
どうにもうまくいかないのは、

コマンドプロンプトの画面では結果が表示されるが、その結果が
Kbunsan.txtに書き込まれない。(何も書き込まれない。)

という状態です。

>wiz様

すいません、なぜかあのプログラムでコンパイルできてしまって…

tに関しては、実は以前プログラムした共分散プログラムを元に
作っているので必要ない文字が入ってしまっていました。

dBは宣言時にdbとスペルミスしてしまっていました。


ご指摘いただいた部分を直してみましたがやはり、指定ファイルに
結果が書き込まれません。

どのようにすればうまくいくのでしょうか?

アドバイス、よろしくお願いいたします。

プログラム
------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    double x[10000];                            /*元の値を入れる変数*/
    double wa;                  /*和の変数*/
    double sekiwa;                /*積和の変数*/
    double sekiwa0;        /*mが0の時の積和の変数*/
    double r[100],dB,suma;
    int i,m,n,l,a;
    FILE *fp1,*fp2;        /*入力ファイル用、出力ファイル用*/

    fp1=fopen("SLEEP.txt","r");     /*fp1にSLEEPからファイルを読み込む*/
    fp2=fopen("Kbunsan.txt","w");            /*fp2からKbunsanにファイルを書き込む*/
    
    if(fp1==NULL){                /*ファイルが読み込めない場合エラーメッセージを表示*/
    printf("ファイルが開けません。\n");
    exit(1);
    }
    
    while(1){                           /*ファイルの終わりにEOFが出てくるまでデータを読み込む*/
    if(fscanf(fp1,"%f",&x[i])==EOF){break;}
    i++;
    }
    
    n=i;

    wa=0;                              /*和の変数を0にする*/
    
    for(i=0;i<n;i++){ 
    wa=wa+x[i];         /*配列の変数の和を計算する*/
    }

    wa=wa/n;                                    /*平均を計算する*/
    
    for(i=0;i<n;i++){ 
    x[i]=x[i]-wa;                        /*元の変数からデータから求めた平均値を引く*/
    }
    
    for(m=0;m<n;m++){
        wa=0;                           /*和の変数を0にする*/
        for(i=0;i<n-m;i++){ 
            wa=wa+x[i]*x[i+m];          /*積和を求める*/
        }
        sekiwa=wa/(n-m);                        /*共分散を求める*/
        if(m==0){                        /*m=0の時のみ共分散R(0)を記憶する*/
            sekiwa0=sekiwa;
        }
    }
    
    for(n=1;n<=50;n++){       /*離散コサイン変換する*/
        suma=0;
        for(l=0;l<=100;l++){
            a=r[l]*cos(2.0*3.141592*n/100.0*l);
            suma=a+suma;
        }
    dB=10*log10(suma/101);
    fprintf(fp2,"%f \n",dB);                    /*結果をファイルfp2に書き込む*/
    }

    fclose(fp1);
    fclose(fp2);                                /*fp1,fp2のファイルを閉じる*/
}



この投稿にコメントする

削除パスワード

No.25200

Re:離散コサイン変換とそのファイル出力
投稿者---nop(2006/01/10 14:04:48)


>コマンドプロンプトの画面では結果が表示されるが、その結果が
>Kbunsan.txtに書き込まれない。(何も書き込まれない。)

fp2 のオープン時のエラーチェックが無いようですが、
fp2 が正しくオープンされている事は確認しましたか?

デバッガでトレースし、
各変数の内容をチェックしていますか?

>tに関しては、実は以前プログラムした共分散プログラムを元に
>作っているので必要ない文字が入ってしまっていました。
>dBは宣言時にdbとスペルミスしてしまっていました。

つまり、掲示板に載せたものと、
現在、動作しているものが違うという事ですね?

何故、HTML変換ツールにコピー&ペーストしないのですか?
コピー&ペーストであれば、上記の様な事はあり得ないはずです。


この投稿にコメントする

削除パスワード

No.25201

Re:離散コサイン変換とそのファイル出力
投稿者---wiz(2006/01/10 14:26:40)


>コマンドプロンプトの画面では結果が表示されるが、その結果が
>Kbunsan.txtに書き込まれない。(何も書き込まれない。)

結果が表示されている=正常終了している
とはかぎりません。
再度提示されたコードではiが初期化されていないため

>if(fscanf(fp1,"%f",&x[i])==EOF){break;}

恐らくここで強制終了します。




この投稿にコメントする

削除パスワード

No.25209

Re:離散コサイン変換とそのファイル出力
投稿者---HIDE(2006/01/11 04:41:39)


レスありがとうございます。

>fp2 のオープン時のエラーチェックが無いようですが、
>fp2 が正しくオープンされている事は確認しましたか?

fp1と同様にfp2のエラーチェックも作成しましたが、問題ないようです。

>デバッガでトレースし、
>各変数の内容をチェックしていますか?

どうもif(fscanf(fp1,"%d",&x[i])==EOF){break;}で

fp1 0x00434d10 {_ptr=0x00000000 <不適切な Ptr> _cnt=0 _base=0x00000000 <不適切な Ptr> ...}  _iobuf *

のように表示されており、またこのときのx[i]の値が
&x[i] 0x0011c65c double *
と表示されます。

その後のwa=wa+x[i]でもx[i]の値が
x[i] 4.347777683403e-322#DEN double
と表示され、おかしいような気がしたのですがどこがおかしいのか…

>つまり、掲示板に載せたものと、
>現在、動作しているものが違うという事ですね?
>>何故、HTML変換ツールにコピー&ペーストしないのですか?
>コピー&ペーストであれば、上記の様な事はあり得ないはずです。

いえ、動作したものをそのままコピー&ペーストで載せています。
前述のようなミスがあったのですが、コンパイルできていたために
見落としてしまっていました。
申し訳ありません。

>再度提示されたコードではiが初期化されていないため
>>if(fscanf(fp1,"%f",&x[i])==EOF){break;}
>恐らくここで強制終了します。

どうも強制終了はしないのですが、i=0を宣言すれば良いでしょうか?


また、共分散の計算がまず間違っているのではないかと思い、
printf("%f \n",sekiwa);
を付け加えたところ、コマンドプロンプト画面に
0.000000
が、ずらっと表示される結果となってしまいました。
共分散の計算ができていないのでしょうか?

それと、お詫びします。
かなり初歩的なミスをしていました。
VSのウィザードからプログラムを作らず、もともと持っていた
他のプログラムを変更して別名で保存していたために、.cppのファイル
しか作成されていませんでした。
ですので、元にしたファイルの.vcprojとなどのファイルを
フォルダ内にコピーし、ご指導を受けプログラムを若干直した結果、
Kbunsan.txtに以下の値が50行書き込まれるようになりました。

-1.#INF00
-1.#INF00
…(以下同様に合計50行)

もちろん求めたい結果ではないのですが…


プログラムだけでなく、数学的な問題も含まれており、
C言語の掲示板で質問させて頂くことに後ろめたさはございますが、
引き続きご指導をお願いできればと思います。

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

プログラム
-----------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    double x[10000];                            /*元の値を入れる変数*/
    double wa;                  /*和の変数*/
    double sekiwa;                /*積和の変数*/
    double r[100],dB,a,suma;
    int i,m,n,l;
    FILE *fp1,*fp2;        /*入力ファイル用、出力ファイル用*/

    fp1=fopen("SLEEP.txt","r");     /*fp1にSLEEPからファイルを読み込む*/
    fp2=fopen("Kbunsan.txt","w");            /*fp2からKbunsanにファイルを書き込む*/
    
    if(fp1==NULL){                /*ファイルが読み込めない場合エラーメッセージを表示*/
    printf("SLEEPファイルが開けません。\n");
    exit(1);
    }
    if(fp2==NULL){                /*ファイルが読み込めない場合エラーメッセージを表示*/
    printf("Kbunsanファイルが開けません。\n");
    exit(1);
    }
    
    i=0;

    while(1){                           /*ファイルの終わりにEOFが出てくるまでデータを読み込む*/
    if(fscanf(fp1,"%d",&x[i])==EOF){break;}
    i++;
    }
    
    n=i;
    wa=0;                              /*和の変数を0にする*/
    
    for(i=0;i<n;i++){ 
    wa=wa+x[i];         /*配列の変数の和を計算する*/
    }

    wa=wa/n;                                    /*平均を計算する*/
    
    for(i=0;i<n;i++){ 
    x[i]=x[i]-wa;                        /*元の変数からデータから求めた平均値を引く*/
    }
    
    for(m=0;m<n;m++){
        wa=0;                           /*和の変数を0にする*/
        for(i=0;i<n-m;i++){ 
            wa=wa+(x[i]*x[i+m]);                /*積和を求める*/
        }
        sekiwa=wa/(n-m);                        /*共分散を求める*/
        printf("%f \n",sekiwa);
    }

    
    for(n=1;n<=50;n++){       /*離散コサイン変換する*/
        suma=0;
        for(l=0;l<=100;l++){
            a=r[l]*cos(2.0*3.141592*n/100.0*l);
            suma=a+suma;
        }
        dB=10*log10(suma/101);
        fprintf(fp2,"%f \n",dB);                /*結果をファイルfp2に書き込む*/
    }

    fclose(fp1);
    fclose(fp2);                                /*fp1,fp2のファイルを閉じる*/
}




この投稿にコメントする

削除パスワード

No.25210

Re:離散コサイン変換とそのファイル出力
投稿者---ぽへぇ(2006/01/11 07:58:17)


>a = r[l]*cos(2.0*3.141592*n/100.0*l);

この行で r[] を使っているけど、これ以前にどこかで r の配列に
代入している(rの配列を初期化している)ところが見当たらないのですが?

せっかくデバッガを使っているのでしたら、最大限に使いましょう。





この投稿にコメントする

削除パスワード

No.25211

Re:離散コサイン変換とそのファイル出力
投稿者---wiz(2006/01/11 12:46:04)


>いえ、動作したものをそのままコピー&ペーストで載せています。
>前述のようなミスがあったのですが、コンパイルできていたために
宣言していない変数を使用したコードがコンパイルできるコンパイラは
現存しないと思いますが。。。?
#少なくとも私は知らないので。。。

>>再度提示されたコードではiが初期化されていないため
>>>if(fscanf(fp1,"%f",&x[i])==EOF){break;}
>>恐らくここで強制終了します。
>どうも強制終了はしないのですが、i=0を宣言すれば良いでしょうか?
rもそうですが、自動変数は初期化されません。
つまり中身に何が入っているか分からないのです。
強制終了しなかったのはiの中身が『たまたま』配列xの要素数以内の
数値だったのでしょう。

結果がおかしいのも初期化していない中身の不定なr[i]を
計算に利用しているからです。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧