venerdì 5 ottobre 2012

Esempio Mandelbrot con GD/C e palette personalizzata

In questo esempio viene creato l'insieme di Mandelbrot utilizzando la libreria GD che si puo' installare in Debian mediante

apt-get install libgd2-noxpm-dev
(esiste una versione che include anche il formato xpm ma nel caso non interessa)

Vengono inoltre presentati due metodi per creare delle palette per la gestione dei colori (entrambe a 256 colori)
Palette 1

Palette 2


Link al progetto

Da compilare con clang -Wall -O3 mand_gd.c -o mand_gd -lgd
-------------------------------------------------------

#include <gd.h>
#include <stdio.h>
#include <math.h>
#include <error.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define RGB2INT(r,g,b)  (b + 256 * g + 256 * 256 * r)

float re_min = -2.0;
float im_min = -1.2;
float re_max = 1.0;
float im_max = 1.2;
int iterazioni = 255;

float a,b;
float x,y,x_new,y_new;
int k,j,i;

FILE *fp = {0};
gdImagePtr img = {0};
char *fname = "./mand_gd.png";
int s, color;
int red, green, blue;
int palette[256] = {0};

int main() {

float re_factor = (re_max-re_min);
float im_factor = (im_max-im_min);

//Inizializza lo schermo
img = gdImageCreateTrueColor(SCREEN_WIDTH, SCREEN_HEIGHT);

// crea la palette
for(s = 0; s < 256; s++) {
red   = (int)(128.0 + 128 * sin(3.1415 * s / 16.0));
green = (int)(128.0 + 128 * sin(3.1415 * s / 32.0));
blue  = (int)(128.0 + 128 * sin(3.1415 * s / 64.0));
palette[s] = RGB2INT(red, green, blue);
}

// crea una seconda palette
s = 0;
for(int ared=0;ared<=255;ared+=51)
{
for(int agreen=0;agreen<=255;agreen+=51)
{
for(int ablue=0;ablue<=255;ablue+=51)
{
palette[s]=RGB2INT(ared,agreen,ablue);
++s;
}
}
}

for (i=0;i<SCREEN_HEIGHT;i++)
{
for (j=0;j<SCREEN_WIDTH;j++)
{
a = re_min+(j*re_factor/SCREEN_WIDTH);
b = im_min+(i*im_factor/SCREEN_HEIGHT);

x = 0;
y = 0;
for (k=0;k<iterazioni;k++)
{
x_new = (x*x)-(y*y)+a;
y_new = (2*x*y)+b;
if (((x_new*x_new)+(y_new*y_new))>4)
{
red   = gdImageRed(img, palette[k]);
green = gdImageGreen(img, palette[k]);
blue  = gdImageBlue(img, palette[k]);
color = gdImageColorAllocate(img, red, green, blue);
gdImageSetPixel(img,j, i, color);
break;
}
x = x_new;
y = y_new;
}
}
}
if((fp = fopen(fname, "w")) == NULL)
  error(1, 0, "Error - fopen(): %s", fname);
 else {
  gdImagePng(img, fp);
  fclose(fp);
 }
gdImageDestroy(img);
return(0);
}


Numeri complessi in C/C++ con GSL e Complex

In questo esempio un paio di metodi in C e C++ per trattare i numeri primi

Fonte : http://www.relisoft.com/science/physics/images/ucircle.gif


Per il caso in C e' stata usata la libreria GNU Scientific Library (GSL) che offre, oltre a decine di altre funzioni, anche gli operatori ed i tipi per i numeri complessi. Per certi versi GSL puo' essere considerata la risposta alle Numerical Recipies in C

In C++ la gestione dei numeri complessi e' gia' inclusa nel linguaggio con un metodo piu' leggibile poiche' utilizza overloading degli operatori (nell'esempio e' stata usato in modo implicito l'overloading dell'operatore + somma)

L'esempio deve essere compilato come
g++ -Wall -O3 complessi.c -o complessi -lgsl 
-----------------------------------------------------------
#include <cstdlib>
#include <iostream>
// GSL
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
// C++
#include <complex>
using namespace std;

using namespace std;

int main(int argc, char *argv[])
{
    //------------ GSL
    cout << "GSL" << endl;
    gsl_complex z,w,u;
    GSL_SET_COMPLEX(&z,3,4);
    cout << "Z : Reale " << GSL_REAL (z) << ":Immaginario " << GSL_IMAG (z) << endl;
    GSL_SET_COMPLEX(&w,4,5);
    cout << "W : Reale " << GSL_REAL (w) << ":Immaginario " << GSL_IMAG (w) << endl;
    u = gsl_complex_add(z,w);
    cout << "Z+W : Reale " << GSL_REAL (u) << ":Immaginario " << GSL_IMAG (u) << endl;

   
    //------------ C++
    cout << endl << "C++" <<endl;
    complex<double> c1(3.0,4.0);
    complex<double> c2(4.0,5.0);
    complex<double> c3= c1 + c2;
    cout << "Reale : "<<real(c3) << ":Immaginario " << imag(c3) << endl;
   
    system("PAUSE");
    return EXIT_SUCCESS;
}

Pi Greco con OpenMP e GMP

Per testare il calcolo parallelo e l'Hyperthreading avevo la necessita' di un algoritmo parallelizzabile e con una convergenza piuttosto lenta per poter apprezzare le differenze di tempo di calcolo nella versione parallela e non parallela.

Scartato il calcolo di Pi Greco mediante la formula di Gauss (gia' utilizzata in un precedente post) perche' ricorsiva e quindi non parallelizzabile e scartato l'insieme di Mandelbrot perche' comunque un minimo complesso , ho provato a determinare il valore di Pi Greco mediante lo sviluppo in serie di Taylor mediante la formula


La sommatoria converge con estrema lentezza al valore di Pi Greco

Standard (tempo di esecuzione 0.049s)
-----------------------------------------------------

#include <cmath>
#include <iostream>

using namespace std;

int main()
{

float pi_s = 0.0;

for (int n=0; n<100000;++n)
{
pi_s = pi_s + (pow(-1,n)/(2*n+1));
}
cout << "Normale " << pi_s*4 << endl <<endl;

return 0;
}
-----------------------------------------------------


OMP (tempo di esecuzione 0.05s)
-----------------------------------------------------

#include <cmath>
#include <iostream>
#include <omp.h>

using namespace std;

int main()
{

float pi_s = 0.0;
#rpragma omp parallel
{
#pragma omp for reduction(+:pi_s) nowait
for (int n=0; n<100000;++n)
{
pi_s = pi_s + (pow(-1,n)/(2*n+1));
}
}
cout << "Normale " << pi_s*4 << endl <<endl;

return 0;
}

-----------------------------------------------------


GMP (tempo di esecuzione 0.1s)
-----------------------------------------------------

#include <cmath>
#include <iostream>
#include <gmp.h>

using namespace std;

int main()
{
mpf_t pi;
mpf_t transi;
mpf_t print;


int sopra;
int sotto;
//float pi_s = 0.0;

mpf_init_set_ui(pi,0);
mpf_init_set_ui(transi,1);
mpf_init_set_ui(print,0);

for (int n=0; n<100000000;++n)
{
sopra = pow(-1,n);
sotto = (2*n)+1;
mpf_set_si(transi,sopra);
mpf_div_ui(transi,transi,sotto);
mpf_add(pi,pi,transi);
mpf_mul_ui(print,pi,4);

//Calcolo eseguito senza GMP
//pi_s = pi_s + (pow(-1,n)/(2*n+1)); 
//cout << "Normale " << pi_s*4 << endl <<endl;
}
gmp_printf("Pi %.Ff\n",print);

return 0;
}



-----------------------------------------------------

L'integrazione di OMP e GMP non e' banale perche' se si uniscono i due esempi sopra riportati il compilatore riporta che la variabile pi has invalid type for ' reduction'

giovedì 4 ottobre 2012

Creare progetti Swing/Java con Eclipse e NetBeans

Eclipse
La procedura per creare un progetto Swing con Eclipse ripercorre per le prime fasi quelle descritte nel precedente post

Per creare le interfacce Swing in Eclipse e' necessario utilizzare un Plugin (Window Builder) che comunque e' gia' presente sia nella versione Java di Eclipse sia nel pacchetto dei Google Plugins (http://dl.google.com/eclipse/plugin/4.2 per la versione di Eclipse Juno)
Si deve creare un Nuovo Progetto Java Application, dopo si seleziona il progetto nella colonna a sinistra del Package Explorer e si crea un nuovo package. A questo punto si clicca sul package e si seleziona New/Other/Swing Designer/Jframe

Al di sotto della finestra di Editor del codice ci sono due tab; tramite questi si puo' accedere all'editor visuale di Swing



NetBeans
Si deve creare un Nuovo Progetto/Java Application. Successivamente si sceglie il nome del progetto e si lascia il flag su Create Main Class ma si cancella il nome della class


A questo punto in Source Packages si legge <default package>. Si clicca destro e si seleziona nuovo JFrame e compare l'editor visuale


Creare PDF in Java

Per creare Pdf da programma in Java esistono diverse soluzioni con differenti potenzialita'

La libreria piu' semplice e' GnuJPdf che gestisce sostanzialmente solo la parte testuale e poco piu' con il
vantaggio di avere una dimensione veramente esigua

GnuJPdf

--------------------------------------------------
package pdf;

import gnu.jpdf.PDFGraphics;
import gnu.jpdf.PDFJob;

import java.awt.Font;
import java.awt.Graphics;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class scrivi {
static OutputStream out;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
out = new BufferedOutputStream (new FileOutputStream (new File ("/home/luca/gnujpdf.pdf")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
        PDFJob job = new PDFJob (out);
        
        Graphics graphics = job.getGraphics ();
        ((PDFGraphics)graphics).setFont (new Font ("Helvetica", Font.PLAIN, 12));
        graphics.drawString ("Esempio di documento PDF", 60, 80);
        graphics.drawString ("Linea di testo", 60, 100);
        graphics.drawString ("Pagina 1", 60, 120);

        // seconda pagina
        graphics = job.getGraphics ();
        ((PDFGraphics)graphics).setFont (new Font ("Helvetica", Font.PLAIN, 12));
        graphics.drawString ("Testo su pagina 2", 60, 80);
        graphics.drawString ("ancora testo", 60, 100);
        graphics.drawString ("Pagina 2", 60, 120);
        graphics.dispose ();

        job.end ();
}
}
--------------------------------------------------
A questo link il risultato del programma

Altrimenti una libreria molto piu' completa e' data da iText che ha una sintassi sostanzialmente
banale e gestisce anche le immagini (con la possibilita' anche di modificarle al volo)

iText
--------------------------------------------------

package com.test.itext;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;

public class Scrivi {

/**
* @param args
* @throws IOException 
* @throws MalformedURLException 
*/
public static void main(String[] args) throws MalformedURLException, IOException {
BufferedOutputStream out = null;
// TODO Auto-generated method stub
try {
out = new BufferedOutputStream (new FileOutputStream (new File ("/home/luca/itext.pdf")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Document doc = new Document ();

        try
        {
            PdfWriter.getInstance (doc, out);
            doc.open ();
            
            doc.add (new Paragraph ("Esempio di documento Pdf"));
            doc.add (new Paragraph ("Linea"));
            doc.add (new Paragraph ("Pagina 1"));
            
            //inserisce una immagine in una posizione specifica e la scala
            Image immagine = Image.getInstance("/home/luca/grafico.png");
            immagine.setAbsolutePosition(100f, 400f);
            immagine.scalePercent(70f);
            doc.add(immagine);

            doc.newPage ();
            doc.add (new Paragraph ("Ancora testo"));
            doc.add (new Paragraph ("--------------"));
            doc.add (new Paragraph ("Pagina due"));
     
        }
        catch (DocumentException e)
        {
            System.out.println ("Fatal PDF error: " + e);
        }

        doc.close ();

}
}
-------------------------------------------------------------------
A questo link il risultato del programma

Crea PNG in Java

Per creare una immagine e salvarla in formato PNG in Java si usano le Buffered Images



L'esempio sotto riportato e' sostanzialmente autoesplicativo
-----------------------------------------

package com.test.png;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Scrivi {

private static BufferedImage bimage;

public static void main(String[] args) {
bimage = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);
int rgb = 0xFF00FF00;
for (int s=10;s<90;++s) bimage.setRGB(s, s, rgb);

File f = new File("/home/luca/immagine_java.png");
try {
ImageIO.write(bimage, "PNG", f);
} catch (IOException e) {

e.printStackTrace();
}
}

}

Minix in QEmu



Si crea prima una immagine vuota da 2 Gb per il disco virtuale
qemu-img create minix.img 2G
 
Poi si imposta il cdrom sulla iso scaricata e hda sul disco virtuale 
facendo boot da cdrom
La memoria e' impostata a 256 Mb (anche troppi visti che il 
sistema e' operativo e' dichiarato come funzionante con 128 Mb ma 
essendo una macchina virtuale ho preferito eccedere
qemu -localtime -m 256 -cdrom minix.iso -hda minix.img -boot d 
 
 
L'installazione e' banale, basta scegliere la modalita' guidata 
e non quella expert
Si riavvia
shutdown
 
Si fa ripartire Qemu scambiando i dischi e partendo da C 
(in questo modo si possono installare i pacchetti extra) 
qemu -localtime  -m 256 -hda minix.img -cdrom minix.iso -boot c
 
 
Per installare i pacchetti addizionali si puo' procedere cosi' 
Lista dei pacchetti disponibili 
pkgin_cd available | more 
Installa GCC 
pkgin_cd install gcc44
Installa X11 
pkgin_cd install X11 

X11/Minix in esecuzione su QEmu


senza l'accelerazione hardware di KQEmu comunque anche un sistema 
operativo leggero come Minix risulta lentissimo all'interno di QEmu

Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...