GnuPlotは独立したひとつのプログラムですから、定数a,b,c を直接利用することはできません。fit.logファイルを読むしかありません。
ソースは2000字制限で全部を載せることができないため、#2の「 input_str();if () else 」文をコピペしてください。
/* Gcc on Mac OSX
* file name: r_aso.c
* compile: gcc r_aso.c
* execution: ./a.out
*/
#include <stdio.h>
#include <stdlib.h> //exit(),system()
#include <string.h> //strtok(),strstr()
#define SIZE 128
#define FILE_NAME "jikken.dat"
#define GP_LOGFILE "fit.log"
#define SPC " "
#define KEYWORD "+/-"
#define input_str(c,x) {printf(c);fgets(x,SIZE,stdin);}
#define set_token(v,x) {strtok(x,SPC);strtok(NULL,SPC);v=atof(strtok(NULL,SPC));}
int main(void) {
int i;
char buff[SIZE];
FILE *fp,*gp;
double a,b,c;
/*ここに
input_str("Data input? (y/n) ",buff);
if (*buff=='y' || *buff=='Y') {
....
をコピペのこと。 */
// ***** GnuPlot *****
if ((gp=popen("gnuplot","w"))==NULL) {
perror("popen");
exit(1);
}
// 既存fit.logファイルの削除
sprintf(buff,"rm %s\n",GP_LOGFILE);
system(buff);
// fit.log の作成
fprintf(gp,"f(x)=a*(1-exp(-b*x))+c \n");
fprintf(gp,"a=5;b=0.1;c=1 \n");
fprintf(gp,"fit f(x) '%s' via a,b,c \n",FILE_NAME);
pclose(gp); //←ここでいったん GnuPlotを閉じる
//定数a,b,c の読み取り
if ((fp=fopen(GP_LOGFILE,"r"))==NULL) {
perror("fopen(GP_LOGFILE)");
exit(1);
}
fgets(buff,SIZE,fp);
while (strstr(buff,KEYWORD)==NULL){
fgets(buff,SIZE,fp);
}
set_token(a,buff);
fgets(buff,SIZE,fp);
set_token(b,buff);
fgets(buff,SIZE,fp);
set_token(c,buff);
fclose(fp);
sprintf(buff,"%f*(1-exp(-%f*x))+%f",a,b,c);
//GnuPlotによる描画
gp=popen("gnuplot","w");
fprintf(gp,"set xrange [0:40] \n");
fprintf(gp,"set yrange [0:8] \n");
fprintf(gp,"set title 'An example' \n");
fprintf(gp,"set xlabel 'X' \n");
fprintf(gp,"set ylabel 'f(x)' \n");
fprintf(gp,"plot '%s' with points pointtype 6 pointsize 1.5 \n",FILE_NAME);
fprintf(gp,"f(x)=%s \n", buff);
fprintf(gp,"replot f(x) with lines title 'f(x)= %s' \n", buff);
pclose(gp);
//結果のターミナル出力
printf("\n");
printf("GnuPlot fitting result:\n");
printf("\tf(x) = %s\n", buff);
return 0;
}
お礼
どうにか最小プログラムで実現できました。 ソフトに組み込んでみます。 本当にありがとうございました。 処理が重くなったときはそのときにほかの方法を考えます。 gnuplotって便利ですね。 gnuplotについてはこれから勉強していきます。