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:

Codice: Seleziona tutto

while((n<1 || n>=10) || (res!=1));
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