質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

gnuplot

gnuplot(ニュープロット)は、2次元や3次元のグラフ作成ができるソフトウェアです。さまざまな数式やデータ集計などのグラフを描写することが可能で、特に2次元グラフを描画する機能は強力です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Q&A

解決済

2回答

1055閲覧

c:ルンゲクッタ法によるプロット時のエラーを解決したい

b6l9kk

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

gnuplot

gnuplot(ニュープロット)は、2次元や3次元のグラフ作成ができるソフトウェアです。さまざまな数式やデータ集計などのグラフを描写することが可能で、特に2次元グラフを描画する機能は強力です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

0グッド

0クリップ

投稿2021/11/15 02:03

前提・実現したいこと

c言語でルンゲクッタ法を用いて出したデータをプロットしたいです。
プログラム内でファイルに書き出すやり方です。

発生している問題・エラーメッセージ

gnuplotでプロットしようとしたら以下のエラーが発生しました。

warning: Skipping data file with no valid points ^ x range is invalid

該当のソースコード

#include<stdio.h> #include<math.h> double f1(double t, double x1, double x2, double x3, double vold, double w, double g); double f2(double t, double x1, double x2, double x3, double vold, double w, double g, int i); int main(){ int i,n; //double alpha; double dt=0.001,tmax,k=23,t=0.0,fk,fs,theta,fz,a,b,g,c; int Nsd[10]; double kx1[10],kv1[10],kx2[10],kv2[10],kx3[10],kv3[10],kx4[10],kv4[10],kw1[10],kw2[10],kw3[10],kw4[10],kg1[10],kg2[10],kg3[10],kg4[10]; double xold[10],xnew[10],vold[10],vnew[10],wold[10],wnew[10],gold[10],gnew[10]; double f[10]; double alpha[10]; n=10; //ブロックの個数 fs=0.7; //静摩擦係数 fk=0.45; //動摩擦係数 fz=60.0; //全荷重 tmax=1.001; theta=0.0; //初期条件 xold[0]=0.0; //xの初期値=0 for(i=0;i<=n-1;i+=1) { xold[i+1]=xold[i]+1.0; } //wold[0]=1.0; for(i=0;i<=n-1;i+=1) { wold[i]=0.0;//全ブロックの荷重の初期値 } for(i=0;i<=n-1;i+=1) { gold[i]=0; //全部のブロックに横向きの力 } for(t=0.0;t<=tmax;t+=dt) { for(i=0;i<=n-1;i++){ Nsd[i]=0; //静的 } for(i=0;i<=n-1;i++){ if(i==0){ if(fs*wold[i] < gold[i]+k*(xold[i+1]-xold[i])) { Nsd[i]=1; //動的 f[i]=fk*wold[i]; //printf("%lf\n",f[i]); } } else if(i==n-1){ if(fs*wold[i] < gold[i]+k*(-xold[i]+xold[i-1])) { Nsd[i]=1; f[i]=fk*wold[i]; //printf("%d %lf\n",i,f[i]); } } else{ if(fs*wold[i] < gold[i]+k*(xold[i+1]-2*xold[i]+xold[i-1])) { Nsd[i]=1; f[i]=fk*wold[i]; //printf("%d %lf\n",i,f[i]); } } } /* for(i=0;i<=n-1;i++) { if(Nsd[i]==0) { f[i]=gold[i]; } } */ for(i=0;i<=n-1;i++){ kx1[i]=dt*f1(t,xold[i-1],xold[i],xold[i+1],vold[i],wold[i],gold[i]); kv1[i]=dt*f2(t,xold[i-1],xold[i],xold[i+1],vold[i],wold[i],gold[i],i); kw1[i]=0; kg1[i]=0; if(Nsd[i]==0){ kx1[i]=0; kv1[i]=0; } } for(i=0;i<=n-1;i++){ kx2[i]=dt*f1(t+dt*0.5,xold[i-1]+kx1[i-1]*0.5,xold[i]+kx1[i]*0.5,xold[i+1]+kx1[i+1]*0.5,vold[i]+kv1[i]*0.5,wold[i]+kw1[i]*0.5,gold[i]+kg1[i]*0.5); kv2[i]=dt*f2(t+dt*0.5,xold[i-1]+kx1[i-1]*0.5,xold[i]+kx1[i]*0.5,xold[i+1]+kx1[i+1]*0.5,vold[i]+kv1[i]*0.5,wold[i]+kw1[i]*0.5,gold[i]+kg1[i]*0.5,i); kw2[i]=0; kg2[i]=0; if(Nsd[i]==0){ kx2[i]=0; kv2[i]=0; } } for(i=0;i<=n-1;i++){ kx3[i]=dt*f1(t+dt*0.5,xold[i-1]+kx2[i-1]*0.5,xold[i]+kx2[i]*0.5,xold[i+1]+kx2[i+1]*0.5,vold[i]+kv2[i]*0.5,wold[i]+kw2[i]*0.5,gold[i]+kg2[i]*0.5); kv3[i]=dt*f2(t+dt*0.5,xold[i-1]+kx2[i-1]*0.5,xold[i]+kx2[i]*0.5,xold[i+1]+kx2[i+1]*0.5,vold[i]+kv2[i]*0.5,wold[i]+kw2[i]*0.5,gold[i]+kg2[i]*0.5,i); kw3[i]=0; kg3[i]=0; if(Nsd[i]==0){ kx3[i]=0; kv3[i]=0; } if(i==n-1){ kx3[i]=dt*f1(t+dt*0.5,xold[i-1]+kx2[i-1]*0.5,xold[i]+kx2[i]*0.5,0,vold[i]+kv2[i]*0.5,wold[i]+kw2[i]*0.5,gold[i]+kg2[i]*0.5); kv3[i]=dt*f2(t+dt*0.5,xold[i-1]+kx2[i-1]*0.5,xold[i]+kx2[i]*0.5,0,vold[i]+kv2[i]*0.5,wold[i]+kw2[i]*0.5,gold[i]+kg2[i]*0.5,i); kw3[i]=0; kg3[i]=0; if(Nsd[i]==0){ kx3[i]=0; kv3[i]=0; } } } for(i=0;i<=n-1;i++){ kx4[i]=dt*f1(t+dt,xold[i-1]+kx3[i-1],xold[i]+kx3[i],xold[i+1]+kx3[i+1],vold[i]+kv3[i],wold[i]+kw3[i],gold[i]+kg3[i]); kv4[i]=dt*f2(t+dt,xold[i-1]+kx3[i-1],xold[i]+kx3[i],xold[i+1]+kx3[i+1],vold[i]+kv3[i],wold[i]+kw3[i],gold[i]+kg3[i],i); kw4[i]=0; kg4[i]=0; if(Nsd[i]==0){ kx4[i]=0; kv4[i]=0; } } for(i=0;i<=n-1;i++){ xnew[i]=xold[i]+(kx1[i]+2.0*kx2[i]+2.0*kx3[i]+kx4[i])/6.0; vnew[i]=vold[i]+(kv1[i]+2.0*kv2[i]+2.0*kv3[i]+kv4[i])/6.0; xold[i]=xnew[i]; vold[i]=vnew[i]; } alpha[9]=10.0; //alpha[0]=5.5; for(i=0;i<=n-1;i++){ //alpha[i+1]=alpha[i]+1.0; //gnew[i]=alpha[i]*t; gnew[i]=alpha[i]*t; gold[i]=gnew[i]; //printf("%lf",gold[i]); if(Nsd[i]==0){ f[i]=gold[i]; } } for(i=0;i<=n-1;i+=1) { //theta+=0.001; wold[i]=(fz/n)*(1+(2*(i+1)-n-1)*theta/(n-1)); //荷重 } b=k*(xold[2]-2*xold[1]+xold[0]); c=(f[0]+f[1]+f[2]+f[3]+f[4]+f[5]+f[6]+f[7]+f[8]+f[9])/10;//摩擦力 g=(gold[0]+gold[1]+gold[2]+gold[3]+gold[4]+gold[5]+gold[6]+gold[7]+gold[8]+gold[9])/10;//駆動力 //printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",t,f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9]); //printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",t,xold[0],xold[1],xold[2],xold[3],xold[4],xold[5],xold[6],xold[7],xold[8],xold[9]); //printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",t,wold[0],wold[1],wold[2],wold[3],wold[4],wold[5],wold[6],wold[7],wold[8],wold[9]); //printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",t,gold[0],gold[1],gold[2],gold[3],gold[4],gold[5],gold[6],gold[7],gold[8],gold[9]); //printf("%lf %d %d %d %d %d %d %d %d %d %d\n",t,Nsd[0],Nsd[1],Nsd[2],Nsd[3],Nsd[4],Nsd[5],Nsd[6],Nsd[7],Nsd[8],Nsd[9]); //printf("%lf %lf\n",t,theta); //printf("%lf %lf\n",t,g); printf("%lf %lf\n",t,c); //printf("%lf %lf\n",t,f[8]); //printf("%lf %lf\n",t,b); } FILE*fp; fp=fopen("run.dat","w"); if(fp==NULL){ printf("cannot open\n"); fclose(fp); } } double f1(double t,double x1, double x2, double x3, double vold, double w, double g) { return (vold); } double f2(double t,double x1, double x2, double x3, double vold, double w, double g, int i) { double fk=0.45,fs=0.7; double a2; int n=10; if(vold==0){ a2=(x1-2.*x2+x3)+g; //a2=0.; if(i==0){ a2=(x3-x2)+g; //a2=0.; } if(i==9){ a2=(x1-x2)+g; //a2=0.; } } else if(vold>0){ a2=(x1-2.*x2+x3)-fk*w+g; // printf("%lf",a2); if(i==0){ a2=(x3-x2)-fk*w+g; } if(i==9){ a2=(x1-x2)-fk*w+g; // printf("%lf",a2); } } else{ a2=(x1-2.*x2+x3)+fk*w+g; //a2=0.; if(i==0){ a2=(x3-x2)+fk*w+g; //a2=0.; } if(i==9){ a2=(x1-x2)+fk*w+g; //a2=0.; } } return (a2); }

データを貼り付けてプロットする方法も教えていただきたいです。

補足情報(FW/ツールのバージョンなど)

言語:C Xcodeを使っています。
プロットはgnuplotを使って行いたいです。

10個のブロックをバネで繋げたモデルで、走る際の荷重の掛け方による摩擦の変化を見るプログラムです。
つま先、足裏全体、踵の3パターンをθなどの値を変えて調べたいと思っています。
お願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/11/15 06:04

main の最後にあるファイルのオープンは何でしょう。
guest

回答2

0

コードが処理毎に関数にされていないので、どこが実際にファイルに出力する必要があるデータの表示なのかがよく分かりませんので、具体的なコードとしてご提示出来ませんが。

要はファイルオープン→出力→クローズであることはお分かりになっていると思います。
そして、 printf には fprintf という亜種(というかこちらが本質?)があります。
printf と同じように書式を指定して出力する関数ですが、 printf は標準出力に出力するのに対し、 fprintf はパラメータとして渡した FILE* に出力します。

ですので、必要な printf を行っている for ループ等を囲うようにファイルオープンとクローズを入れ、 printf を fprintf に変えて FILE* ( ご提示のコードでは fp) をパラメータに追加すれば、ファイルに出力されると思います。

投稿2021/11/15 06:42

jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

b6l9kk

2021/11/15 07:17

回答ありがとうございます。 「FILE* ( ご提示のコードでは fp) をパラメータに追加すれば」のパラメータに追加というのはどういうことでしょうか。 知識不足で申し訳ないです。
jimbe

2021/11/15 07:49

コードを見させて頂いていますが、例えば最初にある xold[0]=0.0; //xの初期値=0 for(i=0;i<=n-1;i+=1) { xold[i+1]=xold[i]+1.0; } は、 i=9 の時に i+1=10 となって xold の定義範囲を超えています。 あちこちに「 i が 0 から n-1 以下の間ループする for 」がありますが、その内部で配列数 10 の配列に対し [i-1] や [i+1] といった位置にアクセスしています。これで大丈夫なのでしょうか。
b6l9kk

2021/11/15 08:18

ご指摘ありがとうございます。 正直、私もそこは疑問です。もう少し調べたいと思います。 過去のプログラムを引き継いでいて、完全に理解できていないのが現状です。
guest

0

ベストアンサー

gnuplotでプロットしようとしたら以下のエラーが発生しました。

エラーではなくワーニングメッセージが表示されていますし、C プログラムの問題ではなく、gnuplot の使い方の問題かと思います。

以下、そのプログラムを実行して出力されるデータをファイル data.dat に保存したとします。

bash

1$ gnuplot 2 3 G N U P L O T 4 Version 5.4 patchlevel 1 last modified 2020-12-01 5 : 6 7gnuplot> set xrange [0.2:0.25] 8gnuplot> plot "data.dat" w p pt 7 lc "blue" title "friction coefficient"

gnuplot

投稿2021/11/15 02:43

melian

総合スコア20655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

b6l9kk

2021/11/15 02:52

ご回答ありがとうございます。 初歩的な質問で申し訳ないのですが、データを保存する際はテキストエディタに貼り付ける方法でしょうか? 保存の仕方を教えていただきたいです。 よろしくお願い致します。
melian

2021/11/15 02:57

ファイルにリダイレクトすれば良いのではないでしょうか。OSX だと思われますので、そのプログラムの名前を例えば calc_friction として、コマンドラインで以下を実行します。 $ ./calc_friction > data.dat
b6l9kk

2021/11/15 04:46

ありがとうございます。 OSはBig Surです。上記を試したら zsh: no such file or directory: となりました。
melian

2021/11/15 04:50

calc_friction という名前は私の方で勝手に付けた名前ですので、実際にお使いのプログラム名に置き換えて実行してみて下さい。
b6l9kk

2021/11/15 05:00

説明不足でした。自分のプログラムの名前で行いました。
melian

2021/11/15 05:04

それではそのプログラムが置かれているディレクトリに移動してから実行してみて下さい。
b6l9kk

2021/11/15 05:34

desktopにプログラム(fric.c)があり、移動してから $ ./fric > data.dat を実行しても zsh: no such file or directory: となってしまいます。
melian

2021/11/15 05:36

では、 ls -l fric の実行結果を教えていただけますか?
b6l9kk

2021/11/15 05:43

No such file or directory となりました。 根本的におかしいのでしょうか。
melian

2021/11/15 05:45

えっと、、、コンパイルしましたか?
melian

2021/11/15 05:48

もしかして a.out というファイルがありませんか?
b6l9kk

2021/11/15 05:52

コンパイルしました。a.outはあります。
melian

2021/11/15 05:55

了解です、それでは以下になります。 ./a.out > data.dat
b6l9kk

2021/11/15 06:02

ありがとうございます。プロットはできました。 追加でお聞きしたいのですが、ルンゲクッタの後の alpha[9]=10.0; の[]内と  gnew[i]=alpha[i]*t; のalpha[]内は何にするのが正しいのでしょうか。 配列は10個で、今回は適当に9としただけです。
jimbe

2021/11/15 06:06

横槍で失礼しますが、リダイレクトは「プログラム内でファイルに書き出すやり方」とは違うと思うのですが、良いのでしょうか。
melian

2021/11/15 06:10

> jimbe あ、そこのところをすっかり見落としていました。。。
b6l9kk

2021/11/15 06:22 編集

>jimbe 最初の私の質問の意図とはずれてしまいますが、プロットができればよかったので、教えていただいたリダイレクトで進めました。 もう一つの質問ですが、初めはファイルに書き出すやり方のつもりだったからです。 「プログラム内でファイルに書き出すやり方」の場合、ファイルのopenの部分で訂正すべきところがあれば教えていただきたいです。
melian

2021/11/15 06:36

> b619kk 遠回りさせてしまってごめんなさい、本回答は無視して下さい。
jimbe

2021/11/15 06:45

> 本回答は無視 このご質問には2つの問題が含まれていたわけですので、プロットに関する件に対しまして有効なのではないでしょうか。
b6l9kk

2021/11/15 08:19

>melian プロットに関してはご丁寧に教えてくださり、感謝しております。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問