何を表しているソースコードなのか分かりません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ne

何を表しているソースコードなのか分かりません

#1

投稿記事 by ne » 8年前

[1.1]課題で与えられたソースコードなのですが, 何をしているコードなのかが分かりません.

[1.2]似たようなソースコードを漁った結果, 動的メモリを確保してファイル内の何かを変更していることがおぼろげながら分かりました.

[1.3]特に関数lsmが何の演算をしているかということと, ptsが何を表している変数なのかが分かりません.

[2.1]環境 : Windows7, gcc

[3.1] C言語初心者です.こういった掲示板で質問するのは初めてなので何か不手際があったら申し訳ありません.

コード:

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

#define MAXPATH 256

int size_data(char *flname)
{
        int i;
        double x;
        FILE *fp;
        
        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                exit(3);
        }
        for(i=0;fscanf(fp, "%le", &x)!=EOF ; i++);
        fclose(fp);
        
        return( 1 );
}


void lsm(double f[], double fs[], int start, int end)
{
        int n,i;
        double si=0, sf=0, sif=0, sii=0, a, b;
        
        n = end - start + 1;
        
        for( i=start ; i<=end ; i++){
                si += i;
                sf +=f[i] ;
                sif += i * f[i];
                sii += (double)i * i;
        }
        a = (n*sif - si *sf) / (n*sii - si*si);
        b = (sf*sii - sif*si) / (n*sii - si*si);
        for( i= start; i<= end; i++){
                fs[i] = i*a +b;
        }
}


int main(int argc, char *argv[])
{
        char flname[MAXPATH];
        int pts, m, n, i, j;
        double *y, *ys;
        FILE *fp;
        
        if(argc != 4){
                fprintf(stderr, "???\n");
                return( 1 );                    
        }
        for( i=1; i<argc ; i++){
                if(*argv[i] == '-'){
                        switch(*++argv[i]){
                                case 'p': pts = atoi(argv[++i]);
                                if(pts %2!=1 || pts ==1){ 
                                        fprintf(stderr, "Illegal parameter\n");
                                        return( 1 );
                                }
                                
                                break;
                                default: fprintf(stderr, "Unknown parameter\n");
                                return( 1 );
                        }
                }else{
                        strcpy(flname, argv[i]);
                }
        }
        
        m = pts/2;
        n = size_data(flname);
        if( n < pts ){
                fprintf(stderr, "Illegal parameter\n");
                return( 1 );
        }
        y = (double *)malloc( n * sizeof(*y));
        ys = (double *)malloc( n * sizeof(*ys));
        if( y == NULL || ys == NULL ) {
                fprintf(stderr, "Not enough memory\n");
                return( 2 );
        }
        
        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                return( 3 );
        }
        for( i=0 ; i<n ; i++ ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                ys[0] = y[0];
                ys[n-1] = y[n-1];
        }else{
                lsm(y, ys, 0, m-1);
                lsm(y, ys, n-m, n-1);
        }
        for( i=m ; i<n-m ; i++){
                ys[i] = 0 ;
                        for( j=-m ; j<=m ; j++){
                                ys[i] += y[i+j];
                        }
                        ys[i] /= pts ;
                }
                
                for( i=0 ; i<n ; i++ ){
                        if( printf("%le\n", ys[i]) == EOF ){
                                fprintf(stderr, "Disk full\n");
                                return( 3 );
                        }
                }
                
                free(y);
                free(ys);
                
                return( 0 );
}

Math

Re: 何を表しているソースコードなのか分かりません

#2

投稿記事 by Math » 8年前

ims はleast squares method 「最小二乗法」の計算で
pts は parameters パラメータ(フィッティングパラメータ)
でしょう。
課題 は言えないのですね。

Math

Re: 何を表しているソースコードなのか分かりません

#3

投稿記事 by Math » 8年前

コメントを沢山入れるとよくわかるようになるでしょう!。[programにコメントは必須アイテムですよ。特に他人に見てもらうのだし..ね!]

コード:

#include<stdio.h>  //
#include<stdlib.h> //  [ lms ] least squares method  「最小二乗法」
#include<string.h> //
                   //
#define MAXPATH 256//
                   //
int size_data(char *flname)
{
        int i;
        double x;
        FILE *fp;
        
        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                exit(3);
        }
        for(i=0;fscanf(fp, "%le", &x)!=EOF ; i++);
        fclose(fp);
        
        return( 1 );
}
 
 
void lsm(double f[], double fs[], int start, int end)//
{                    //最小二乗法(さいしょうにじょうほう、さいしょうじじょうほう;最小自乗法とも
        int n,i;    //よい近似となるように、残差の二乗和を最小とするような係数を決定する方法
        double si=0, sf=0, sif=0, sii=0, a, b;
        
        n = end - start + 1;
        
        for( i=start ; i<=end ; i++){
                si += i;
                sf +=f[i] ;
                sif += i * f[i];
                sii += (double)i * i;
        }
        a = (n*sif - si *sf) / (n*sii - si*si);
        b = (sf*sii - sif*si) / (n*sii - si*si);
        for( i= start; i<= end; i++){
                fs[i] = i*a +b;
        }
}
 
 
int main(int argc, char *argv[]) // 引数:argc--引数の数     arg[0]-exe自身--arg[1]--arg[2]--arg[3]--
{
        char flname[MAXPATH];         //--flnamm[]---File Name--
        int pts, m, n, i, j;         //--pts--pts は parameters---m--n--i--j-- ==>int型
        double *y, *ys;             //--y--ys-------------doubleのPointor--
        FILE *fp;                  //--fp---File Pointor--
                                  //
        if(argc != 4){                     //--引数が4でないと--
                fprintf(stderr, "???\n"); //--エラー表示する--
                return( 1 );             //--1を返す
        }                               //
        for( i=1; i<argc ; i++){       //---------------------------------------------------------------->>>
                if(*argv[i] == '-'){                                //-- '-'
                        switch(*++argv[i]){                        //--[-〇]の〇でswitch
                                case 'p': pts = atoi(argv[++i]);  //--p	次の文字を整数化
                                if(pts %2!=1 || pts ==1){        //--
                                        fprintf(stderr, "Illegal parameter\n");//--パラメーターが不正
                                        return( 1 );                          //--1を返す
                                }
                                
                                break;                                            //--break;--
                                default: fprintf(stderr, "Unknown parameter\n"); //--変なparameterだわね!
                                return( 1 );                                    //--1を返す--
                        }
                }else{
                        strcpy(flname, argv[i]);//--File Name を保存--
                }
        }//------------------------------------------------------------------------------------------------<<<
        
        m = pts/2;                                    
        n = size_data(flname);
        if( n < pts ){
                fprintf(stderr, "Illegal parameter\n");
                return( 1 );
        }
        y = (double *)malloc( n * sizeof(*y));   //動的メモリを確保してファイル内の何かを変更していることがおぼろげなが...
        ys = (double *)malloc( n * sizeof(*ys));//--その通り[malloc]はメモリの 動的確保し変数y、ysにfscanfで得たものを代入..
        if( y == NULL || ys == NULL ) {
                fprintf(stderr, "Not enough memory\n");
                return( 2 );
        }
        
        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                return( 3 );
        }
        for( i=0 ; i<n ; i++ ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                ys[0] = y[0];
                ys[n-1] = y[n-1];
        }else{
                lsm(y, ys, 0, m-1);
                lsm(y, ys, n-m, n-1);
        }
        for( i=m ; i<n-m ; i++){
                ys[i] = 0 ;
                        for( j=-m ; j<=m ; j++){
                                ys[i] += y[i+j];
                        }
                        ys[i] /= pts ;
                }
                
                for( i=0 ; i<n ; i++ ){
                        if( printf("%le\n", ys[i]) == EOF ){
                                fprintf(stderr, "Disk full\n");
                                return( 3 );
                        }
                }
                
                free(y);
                free(ys);
                
                return( 0 );
}
//[1.1]課題で与えられたソースコードなのですが, 何をしているコードなのかが分かりません.

//[1.2]似たようなソースコードを漁った結果, 動的メモリを確保してファイル内の何かを変更していることがおぼろげながら分かりました.
                                           *** 上記
//[1.3]特に関数lsmが何の演算をしているかということと, ptsが何を表している変数なのかが分かりません. 
                *** least squares method 「最小二乗法」:::pts は parameters パラメータ(フィッティングパラメータ)
//[2.1]環境 : Windows7, gcc::[IDEはなし?]
                ***Windows7は安定して使い易ですね。事務用に一台使ってます。
//[3.1] C言語初心者です.こういった掲示板で質問するのは初めてなので何か不手際があったら申し訳ありません.::[ここの管理人さんはおおらかですよ]

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 何を表しているソースコードなのか分かりません

#4

投稿記事 by みけCAT » 8年前

オフトピック
ne さんが書きました:

コード:

int size_data(char *flname)
{
        int i;
        double x;
        FILE *fp;
        
        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                exit(3);
        }
        for(i=0;fscanf(fp, "%le", &x)!=EOF ; i++);
        fclose(fp);
        
        return( 1 );
}
ファイルを開いて、データ数を数えるけどその結果は闇に葬って戻る。
実質ファイルが開けるかの確認ですね。
また、ファイルの中に実数として読めない文字列があると、無限ループになりますね。
ne さんが書きました:

コード:

        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                return( 3 );
        }
        for( i=0 ; i<n ; i++ ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
fcloseした後にファイルを読もうとするのは、どうなのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Math

Re: 何を表しているソースコードなのか分かりません

#5

投稿記事 by Math » 8年前

>[1.1]課題で与えられたソースコードなのですが, 何をしているコードなのかが分かりません.
与えられたソースコードだと思ってたけど。エラーなくビルド出来て ??? が表示されたから疑わなかったけど。どう見ても与えられたソースコードではなく”自分で書いたソースコード”でしょうね。(それとも変な先生でからかってる?...)

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 何を表しているソースコードなのか分かりません

#6

投稿記事 by usao » 8年前

「lsmが何の演算をしているか」という質問に対して,
「最小二乗法」とだけ言うのでは説明不足ではないでしょうか.
(これでは単にLSMが何の略称なのかを述べたに過ぎない.ノーヒント状態よりはマシでしょうが.)

関数lsm()は,
データ点群 ( i, f ) start≦i≦end への直線当てはめを行っているのでしょう.
(直線の式は y = a*x + b を使っているように見えるので,y方向残差を見るタイプ.)
この関数の出力はfs[]であり,当てはめた直線上での a*i + b 値を入れています.

…という私の推測が仮に当たっているとすれば

>pts は parameters パラメータ(フィッティングパラメータ)

という言い方は変に思います.
ここで「フィッティングパラメータ」と言えば,それは直線のパラメータである aとb でしょう.
(じゃあptsは何なのかと言うと…
何やらmの値を決めるのに使っている謎の値…?
mは関数lsm()に渡すデータを2グループに分割するための値っぽいですが,
何故mの値を直接入力せずにptsを経由するのだろう…? とか,そこらへんの意味合いはわかりません.
ptsという変数名は,データ点の個数的な意味で points とかの略とか?)

Math

Re: 何を表しているソースコードなのか分かりません

#7

投稿記事 by Math » 8年前

http://mathtrain.jp/leastsquares
http://pc-physics.com/saisyounizyouhou1.html
を参照して頑張って解いてください。

コード:


#include<stdio.h>  //
#include<stdlib.h> //  [ lms ] least squares method  「最小二乗法」
#include<string.h> //
                   //
#define MAXPATH 256//
                   //
int size_data(char *flname)                       //
{                                                 //
        int i;                                    //
        double x;                                 //
        FILE *fp;                                 //
                                                  //
        if((fp=fopen(flname, "r")) == NULL ){     //
                fprintf(stderr, "Can't open: %s\n", flname);//
        }                                         //
                exit(3);                          //
        for(i=0;fscanf(fp, "%le", &x)!=EOF ; i++);//
        fclose(fp);                               //
                                                  //
        return( 1 );                              //
}                                                 //   
                                                  //
                                                  //
void lsm(double f[], double fs[], int start, int end)// f    fs    start    end
{                    //最小二乗法(さいしょうにじょうほう、さいしょうじじょうほう;最小自乗法とも
        int n,i;    //よい近似となるように、残差の二乗和を最小とするような係数を決定する方法
        double si=0, sf=0, sif=0, sii=0, a, b;    //
                                                  //    誤差を二乗し[正の値]とし総和の最小となる点を求む==>>
        n = end - start + 1;                      //    "a,bの偏微分値=0の時の連立方程式を解けばよい
                                                  //
        for( i=start ; i<=end ; i++){             // start≦i≦end----[a*x + b]
                si += i;                          //
                sf +=f[i] ;                       //
                sif += i * f[i];                  //
                sii += (double)i * i;             //
        }                                         //
        a = (n*sif - si *sf) / (n*sii - si*si);   //     --連立方程式の解より...--
        b = (sf*sii - sif*si) / (n*sii - si*si);  //
        for( i= start; i<= end; i++){             //
                fs[i] = i*a +b;                   // Σfs[i] ==> y = a*x + b ::a,b==>>フィッティングパラメータ
        }
}
 
 
int main(int argc, char *argv[]) // 引数:argc--引数の数     arg[0]-exe自身--arg[1]--arg[2]--arg[3]--
{
        char flname[MAXPATH];         //--flnamm[]---File Name--
        int pts, m, n, i, j;         //--pts--pts は parameters---m--n--i--j-- ==>int型
        double *y, *ys;             //--y--ys-------------doubleのPointor--
        FILE *fp;                  //--fp---File Pointor--
                                  //
        if(argc != 4){                     //--引数が4でないと--
                fprintf(stderr, "???\n"); //--エラー表示する--
                return( 1 );             //--1を返す
        }                               //
        for( i=1; i<argc ; i++){       //---------------------------------------------------------------->>>
                if(*argv[i] == '-'){                                //-- '-'
                        switch(*++argv[i]){                        //--[-〇]の〇でswitch
                                case 'p': pts = atoi(argv[++i]);  //--p	次の文字を整数化
                                if(pts %2!=1 || pts ==1){        //--
                                        fprintf(stderr, "Illegal parameter\n");//--パラメーターが不正
                                        return( 1 );                          //--1を返す
                                }
                                
                                break;                                            //--break;--
                                default: fprintf(stderr, "Unknown parameter\n"); //--変なparameterだわね!
                                return( 1 );                                    //--1を返す--
                        }
                }else{
                        strcpy(flname, argv[i]);//--File Name を保存--
                }
        }//------------------------------------------------------------------------------------------------<<<
        
        m = pts/2;                                    
        n = size_data(flname);
        if( n < pts ){
                fprintf(stderr, "Illegal parameter\n");
                return( 1 );
        }
        y = (double *)malloc( n * sizeof(*y));   //動的メモリを確保してファイル内の何かを変更していることがおぼろげなが...
        ys = (double *)malloc( n * sizeof(*ys));//--その通り[malloc]はメモリの 動的確保し変数y、ysにfscanfで得たものを代入..
        if( y == NULL || ys == NULL ) {
                fprintf(stderr, "Not enough memory\n");
                return( 2 );
        }
        
        if((fp=fopen(flname, "r")) == NULL ){
                fprintf(stderr, "Can't open: %s\n", flname);
                return( 3 );
        }
        for( i=0 ; i<n ; i++ ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                fscanf(fp, "%le", &y[i]);
        }
        fclose(fp);
        
        if( m == 1 ){
                ys[0] = y[0];
                ys[n-1] = y[n-1];
        }else{
                lsm(y, ys, 0, m-1);
                lsm(y, ys, n-m, n-1);
        }
        for( i=m ; i<n-m ; i++){
                ys[i] = 0 ;
                        for( j=-m ; j<=m ; j++){
                                ys[i] += y[i+j];
                        }
                        ys[i] /= pts ;
                }
                
                for( i=0 ; i<n ; i++ ){
                        if( printf("%le\n", ys[i]) == EOF ){
                                fprintf(stderr, "Disk full\n");
                                return( 3 );
                        }
                }
                
                free(y);
                free(ys);
                
                return( 0 );
}
//[1.1]課題で与えられたソースコードなのですが, 何をしているコードなのかが分かりません.

//[1.2]似たようなソースコードを漁った結果, 動的メモリを確保してファイル内の何かを変更していることがおぼろげながら分かりました.
//                                           *** 上記
//[1.3]特に関数lsmが何の演算をしているかということと, ptsが何を表している変数なのかが分かりません. 
//                *** least squares method 「最小二乗法」:::pts は points...
//[2.1]環境 : Windows7, gcc::[IDEはなし?]
//                ***Windows7は安定して使い易ですね。事務用に一台使ってます。
//[3.1] C言語初心者です.こういった掲示板で質問するのは初めてなので何か不手際があったら申し訳ありません.::[ここの管理人さんはおおらかですよ]

閉鎖

“C言語何でも質問掲示板” へ戻る