Pagina 5 di 5
Re: [c]utilizzare gnuplot
Inviato: mercoledì 13 maggio 2009, 19:04
da cristian_c
Aggiorno:
ottengo errore anche se faccio la stessa cosa da gnuplot invece che dal programma c. quindi il problema non è nel codice c, ma in gnuplot.
Codice: Seleziona tutto
cristiancozzolino@cristian-desktop:~$ gnuplot
G N U P L O T
Version 4.2 patchlevel 4
last modified Sep 2008
System: Linux 2.6.28-11-generic
Copyright (C) 1986 - 1993, 1998, 2004, 2007, 2008
Thomas Williams, Colin Kelley and many others
Type `help` to access the on-line reference manual.
The gnuplot FAQ is available from http://www.gnuplot.info/faq/
Send bug reports and suggestions to <http://sourceforge.net/projects/gnuplot>
Terminal type set to 'wxt'
gnuplot> set logscale x 10
gnuplot> plot[0:10**(5)]x**(0.200000)
x range must be greater than 0 for log scale
gnuplot>
Re: [c]utilizzare gnuplot
Inviato: sabato 30 maggio 2009, 13:17
da cristian_c
Il codice adesso è questo:
Codice: Seleziona tutto
#include <stdio.h>
#include <math.h>
#define ERR 0.00001
int ordine(double x)
{
int n=0;
while (floor(x)!=0) {
x=x/10;
n++;
}
return n;
}
main()
{
char *indice[]={"quadrata","cubica","quarta","quinta","sesta","settima","ottava","nona","decima"};
long double a,b,m,x;
long double fm,pot;
int n,i,res;
char x_str[50];
printf("\n// il programma calcola la radice\n// di un numero reale positivo scelto dall'utente\n// con indice intero immesso da tastiera\n\n");
do {
printf("Inserire un indice valido per la radice(un numero intero da 1 a 10): ");
res=scanf("%d",&n);
while(getc(stdin)!='\n');
} while((n<1 || n>10) && (res==0));
do {
printf("Inserire un valore reale di cui calcolare la radice: ");
res=scanf("%s",x_str);
while(getc(stdin)!='\n');
} while(res==0);
sscanf(x_str,"%Lf",&x);
if (x>=0) {
if (n==1) printf("\nla radice prima di %s è %s\n",x_str,x_str);
else if (x==1) printf("\nla radice %s di 1 è 1\n\n",indice[n-2]);
else {
if (x>1) {
a=1; b=x;
}
else {
a=x; b=1;
}
do {
m=(a+b)/2;
pot=m;
for(i=1;i<n;i++) pot*=m;
fm=pot-x;
if (fm!=0) {
if (fm>0) b=m;
else a=m;
}
} while (fabs(fm)>ERR);
printf("\nla radice %s di %s è %Lg\n\n",indice[n-2],x_str,m);
}
char cmd[100];
float f = 1/(float)n;
sprintf(cmd,"echo \"plot[0:10**(%d)]x**(%f)\" | gnuplot -persist",ordine(x),f);
printf("il comando che invio è %s\n", cmd);
system(cmd);
}
else printf("Il numero reale digitato non è positivo.\n\n");
}
Ho fatto un tentativo e sembra che per adesso vada molto bene:
Codice: Seleziona tutto
cristiancozzolino@cristian-desktop:~/programmazione$ ./radice
// il programma calcola la radice
// di un numero reale positivo scelto dall'utente
// con indice intero immesso da tastiera
Inserire un indice valido per la radice(un numero intero da 1 a 10): 5
Inserire un valore reale di cui calcolare la radice: 3456
la radice quinta di 3456 è 5.1017
il comando che invio è echo "plot[0:10**(4)]x**(0.200000)" | gnuplot -persist
cristiancozzolino@cristian-desktop:~/programmazione$
Allego l'imagine di gnuplot.
Comunque adesso mi restano da fare alcune piccole(?) cose.
Re: [c]utilizzare gnuplot
Inviato: mercoledì 5 agosto 2009, 17:07
da cristian_c
Ho 'rilasciato' ( ;D ) la nuova versione del programma, ma ho notato un paio di problemi :(
1) Viene disegnata sul grafico la sola linea orizzontale che intercetta il punto desiderato, anche se dall'output si vede che qualcosa è andato storto (yes)
Codice: Seleziona tutto
cristiancozzolino@cristian-laptop:~/programmazione$ ./radice
// il programma calcola la radice
// di un numero reale positivo scelto dall'utente
// con indice intero immesso da tastiera
Inserire un indice valido per la radice(un numero intero da 1 a 10): 5
Inserire un valore reale di cui calcolare la radice: 5000
la radice quinta di 5000 è 5.4928
il comando che invio è echo "set arrow from 5000 to 5000**0.200000 nohead lt 0;set arrow from 0,5000**0.200000 to 5000,5000**0.200000 nohead lt 0;plot[0:10**4]x**0.200000" | gnuplot -persist
*** stack smashing detected ***: ./radice terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7f27da8]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7f27d60]
./radice[0x8048ad8]
/lib/tls/i686/cmov/libc.so.6[0xb7e40074]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:06 1245237 /home/cristiancozzolino/programmazione/radice
08049000-0804a000 r--p 00000000 08:06 1245237 /home/cristiancozzolino/programmazione/radice
0804a000-0804b000 rw-p 00001000 08:06 1245237 /home/cristiancozzolino/programmazione/radice
09f85000-09fa6000 rw-p 09f85000 00:00 0 [heap]
b7e29000-b7e2a000 rw-p b7e29000 00:00 0
b7e2a000-b7f86000 r-xp 00000000 08:01 482454 /lib/tls/i686/cmov/libc-2.9.so
b7f86000-b7f87000 ---p 0015c000 08:01 482454 /lib/tls/i686/cmov/libc-2.9.so
b7f87000-b7f89000 r--p 0015c000 08:01 482454 /lib/tls/i686/cmov/libc-2.9.so
b7f89000-b7f8a000 rw-p 0015e000 08:01 482454 /lib/tls/i686/cmov/libc-2.9.so
b7f8a000-b7f8d000 rw-p b7f8a000 00:00 0
b7f8d000-b7fb1000 r-xp 00000000 08:01 482462 /lib/tls/i686/cmov/libm-2.9.so
b7fb1000-b7fb2000 r--p 00023000 08:01 482462 /lib/tls/i686/cmov/libm-2.9.so
b7fb2000-b7fb3000 rw-p 00024000 08:01 482462 /lib/tls/i686/cmov/libm-2.9.so
b7fb7000-b7fc4000 r-xp 00000000 08:01 457920 /lib/libgcc_s.so.1
b7fc4000-b7fc5000 r--p 0000c000 08:01 457920 /lib/libgcc_s.so.1
b7fc5000-b7fc6000 rw-p 0000d000 08:01 457920 /lib/libgcc_s.so.1
b7fc6000-b7fca000 rw-p b7fc6000 00:00 0
b7fca000-b7fcb000 r-xp b7fca000 00:00 0 [vdso]
b7fcb000-b7fe7000 r-xp 00000000 08:01 457879 /lib/ld-2.9.so
b7fe7000-b7fe8000 r--p 0001b000 08:01 457879 /lib/ld-2.9.so
b7fe8000-b7fe9000 rw-p 0001c000 08:01 457879 /lib/ld-2.9.so
bfad3000-bfae8000 rw-p bffeb000 00:00 0 [stack]
Aborted
cristiancozzolino@cristian-laptop:~/programmazione$
Forse devo agire sui valori, ma come? ??? In allegato il grafico.
2) Non funziona il controllo sull'indice in apertura del programma. Ho provato ad aggiustarlo ma non cambia niente:
Codice: Seleziona tutto
cristiancozzolino@cristian-laptop:~/programmazione$ ./radice
// il programma calcola la radice
// di un numero reale positivo scelto dall'utente
// con indice intero immesso da tastiera
Inserire un indice valido per la radice(un numero intero da 1 a 10): 5000
Inserire un valore reale di cui calcolare la radice: 45
Segmentation fault
cristiancozzolino@cristian-laptop:~/programmazione$
Spero che possiate darmi una mano

Re: [c]utilizzare gnuplot
Inviato: lunedì 17 agosto 2009, 9:40
da cristian_c
2) il secondo errore era banale, infatti la linea giusta di codice era:
1) qui invece avevo sbagliato a scrivere bene i comandi di gnuplot. Adesso l'immagine viene visualizzata bene. In allegato lo screenshot.
questo è l'output:
Codice: Seleziona tutto
cristiancozzolino@cristian-laptop:~/programmazione$ ./radice
// il programma calcola la radice
// di un numero reale positivo scelto dall'utente
// con indice intero immesso da tastiera
Inserire un indice valido per la radice(un numero intero da 1 a 10): 11
Inserire un indice valido per la radice(un numero intero da 1 a 10): 5
Inserire un valore reale di cui calcolare la radice: 5000
la radice quinta di 5000 è 5.4928
il comando che invio è echo "set arrow from 5000 to 5000,5000**0.200000 nohead lt 0;set arrow from 0,5000**0.200000 to 5000,5000**0.200000 nohead lt 0;plot[0:10**4]x**0.200000" | gnuplot -persist
cristiancozzolino@cristian-laptop:~/programmazione$
Adesso l'ultima cosa da fare è inserire una legenda come si deve e togliere la scritta attuale che a mio parere è molto brutta (yes)
Re: [c]utilizzare gnuplot
Inviato: sabato 24 aprile 2010, 22:46
da cristian_c
Sono riuscito a completare il programma inserendo anche la legenda (ovviamente occorre prima installare tex) (b2b)
Il sorgente finale del programma è questo:
Codice: Seleziona tutto
#include <stdio.h>
#include <math.h>
#define ERR 0.00001
int ordine(double x)
{
int n=0;
while (floor(x)!=0) {
x=x/10;
n++;
}
return n;
}
main()
{
char *indice[]={"quadrata","cubica","quarta","quinta","sesta","settima","ottava","nona","decima"};
long double a,b,m,x;
long double fm,pot;
int n,i,res;
char x_str[50];
printf("\n// il programma calcola la radice\n// di un numero reale positivo scelto dall'utente\n// con indice intero immesso da tastiera\n\n");
do {
printf("Inserire un indice valido per la radice(un numero intero da 1 a 10): ");
res=scanf("%d",&n);
while(getc(stdin)!='\n');
} while((n<1 || n>10) || (res!=1));
do {
printf("Inserire un valore reale di cui calcolare la radice: ");
res=scanf("%s",x_str);
while(getc(stdin)!='\n');
} while(res==0);
sscanf(x_str,"%Lf",&x);
if (x>=0) {
if (n==1) printf("\nla radice prima di %s è %s\n",x_str,x_str);
else if (x==1) printf("\nla radice %s di 1 è 1\n\n",indice[n-2]);
else {
if (x>1) {
a=1; b=x;
}
else {
a=x; b=1;
}
do {
m=(a+b)/2;
pot=m;
for(i=1;i<n;i++) pot*=m;
fm=pot-x;
if (fm!=0) {
if (fm>0) b=m;
else a=m;
}
} while (fabs(fm)>ERR);
printf("\nla radice %s di %s è %Lg\n\n",indice[n-2],x_str,m);
}
char gnuplot[200];
float f = 1/(float)n;
sprintf(gnuplot,"echo \"set terminal epslatex color;set output 'gnuplot.eps';set arrow from %s to %s,%s**%f nohead lt 0 lw 0;set arrow from 0,%s**%f to %s,%s**%f nohead lt 0 lw 0;plot[0:10**%d]x**%f ti '$\\sqrt[%d]{x}$'\" | gnuplot",x_str,x_str,x_str,f,x_str,f,x_str,x_str,f,ordine(x),f,n);
system(gnuplot);
FILE *out = fopen( "main.tex", "w" );
fprintf(out,"\\documentclass{article}\n\\usepackage{graphicx}\n\\pagestyle{empty}\n\\begin{document}\n\\input{gnuplot}\n\\end{document}");
fclose(out);
system("epstopdf gnuplot.eps;pdflatex main.tex;evince main.pdf");
}
else printf("Il numero reale digitato non è positivo.\n\n");
}
In allegato un'immagine del risultato