martedì 30 ottobre 2012

Disegnare grafici in Android con GrahView

Un'altra libreria (oltre alla gia' citata AndroidPlot) per disegnare grafici su Android e' GraphView

Rispetto alla precedente e' meno commentata ed di utilizzo un po' piu' difficile ma permette di mostrare dati in realtime ed ha lo zoom ed il pan dinamico mediante gesture

Un po' di indicazioni: il tutorial sul sito dello sviluppatore funziona solo con la versione 2.0 (al momento della scrittura di questo post la versione piu' recente e' la 3.0); per questo motivo anche io ho usato la versione 2

Inoltre di default i colori delle label sugli assi delle ascisse e delle ordinate ed il titolo sono bianchi per cui iniziando un progetto da zero con il nuovo SDK si deve cambiare il colore di background della activity (che gia' di suo e' bianco) altrimenti scompare tutto

-------------------------------------------
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     android:background="#000000" >

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/graph1" />
       
</RelativeLayout>

-------------------------------------------
Usando il codice sotto riportato (un misto tra il codice di esempio ed alcune righe che ho inserito io)  si ha come risultato questa immagine




-------------------------------------------
package com.test.graph;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Menu;
import android.widget.LinearLayout;

import com.jjoe64.graphview.GraphView.GraphViewData;
import com.jjoe64.graphview.GraphView.GraphViewSeries;
import com.jjoe64.graphview.GraphView.LegendAlign;
import com.jjoe64.graphview.LineGraphView;

public class MainActivity extends Activity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        int num = 150; 
        GraphViewData[] data = new GraphViewData[num]; 
        double v=0; 
        for (int i=0; i<num; i++) { 
           v += 0.2; 
           data[i] = new GraphViewData(i, Math.sin(v)); 
        } 
        GraphViewSeries seriesSin = new GraphViewSeries("Seno", Color.rgb(200, 50, 00), data); 
       
        //attenzione l'array dei dati deve essere completo
        //se si omette per esempio di dichiarare dati[4] il programma genera una eccezione
        GraphViewData[] dati = new GraphViewData[5];
        dati[0] = new GraphViewData(0,0);
        dati[1] = new GraphViewData(10,0.5);
        dati[2] = new GraphViewData(15,1.5);
        dati[3] = new GraphViewData(17,0.7);
        dati[4] = new GraphViewData(22,0.7);

       
        GraphViewSeries seriedati = new GraphViewSeries("Misure", Color.rgb(0, 250, 00), dati);
       
        LineGraphView graphView = new LineGraphView( 
              this 
              , "Titolo Grafico" 
        );
       
        // aggiungi la serie dati
        graphView.addSeries(seriesSin);
        graphView.addSeries(seriedati); 
     
        // finestra di visualizzazione del grafico 
        graphView.setViewPort(0, 20); 
        graphView.setScrollable(true); 
        graphView.setScalable(true); 
       
        // Legenda 
        graphView.setShowLegend(true); 
        graphView.setLegendAlign(LegendAlign.BOTTOM); 
        graphView.setLegendWidth(70);
         
        LinearLayout layout = (LinearLayout) findViewById(R.id.graph1); 
        layout.addView(graphView); 
    }

  

venerdì 26 ottobre 2012

Errore su Toast in Android

Un esempio di come puo' avere dei trabocchetti la programmazione su Android anche su cose semplici come la creazione di un widget Toast



Nel referenziare il context del comando Toast.maketext e' necessario riportare il nome della activity in cui si sviluppa il comando (in questo caso MainActivity) altrimenti si genera un errore
   
------------------------------------------------------
btngraph.setOnClickListener(new View.OnClickListener() {
               private Toast toast;
                public void onClick(View v) {

                       // Questo genera un errore
 
                        toast = Toast.makeText(this, R.string.errore, Toast.LENGTH_LONG);
 
                       // Questo NON genera un errore                         toast = Toast.makeText(MainActivity.this, R.string.errore, Toast.LENGTH_LONG);
 


                       toast.show();
                    }

Leggere DMG su Linux

Puo' accadere, specialmente adesso che Apple la sta facendo da padrona, di dover spacchettare un file .dmg ....come fare senza un Mac a disposizione ??



per prima cosa si scarica dmg2iso

apt-get install dmg2iso

in seguito si converte in formato img
dmg2iso pacchetto.dmg

quindi si monta il modulo per il file system hfsplus e si monta il file immagine

modprobe hfsplus
mount -t hfsplus -o loop pacchetto.img /media/sdc

lunedì 22 ottobre 2012

Scambiare dati tra due Activity in Android


Per passare i dati tra due Acitivity, senza la necessita' di dichiarare variabili globali, si puo' usare un Bundle e inserirci i valori (specificando il formato di ogni variabile)

Di seguito un esempio 
 
Attivita' 1 : spedisce i dati 
----------------------------------------------------------------------------------
Bundle dataBundle = new Bundle();
dataBundle.putInt("gradini", gradino);
                  
dataBundle.putDouble("portata1", Double.parseDouble(portata1.getText().toString()));
dataBundle.putDouble("soggiacenza1", Double.parseDouble(soggiacenza1.getText().toString()));
dataBundle.putDouble("portata2", Double.parseDouble(portata2.getText().toString()));
dataBundle.putDouble("soggiacenza2", Double.parseDouble(soggiacenza2.getText().toString()));
dataBundle.putDouble("portata3", Double.parseDouble(portata3.getText().toString()));
dataBundle.putDouble("soggiacenza3", Double.parseDouble(soggiacenza3.getText().toString()));
dataBundle.putDouble("portata4", Double.parseDouble(portata4.getText().toString()));
dataBundle.putDouble("soggiacenza4", Double.parseDouble(soggiacenza4.getText().toString()));
dataBundle.putDouble("portata5", Double.parseDouble(portata5.getText().toString()));
dataBundle.putDouble("soggiacenza5", Double.parseDouble(soggiacenza5.getText().toString()));
 

Intent Intentdati = new Intent(); 
Intentdati.setClass(MainActivity.this,Grafico.class);
Intentdati.putExtras(dataBundle);
startActivity(Intentdati);

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

Attivita' 2 : riceve i dati
----------------------------------------------------------------------------------
 public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grafico);
 

Bundle da = getIntent().getExtras();
gradini = da.getInt("gradini");
portata1 = da.getDouble("portata1");
soggiacenza1 = da.getDouble("soggiacenza1");
portata2 = da.getDouble("portata2");
soggiacenza2 = da.getDouble("soggiacenza2");
portata3 = da.getDouble("portata3");
soggiacenza3 = da.getDouble("soggiacenza3");
portata4 = da.getDouble("portata4");
soggiacenza4 = da.getDouble("soggiacenza4");
portata5 = da.getDouble("portata5");
soggiacenza5 = da.getDouble("soggiacenza5");

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

venerdì 19 ottobre 2012

Pulire la cache dei file Deb in Debian

Nel caso in cui sia necessario libera spazio da una Debian si puo' rimuovere la cache dei pacchetti .deb che sono contenuti nelle seguenti directory

/var/cache/apt/archives
/var/cache/apt/archives/partial

la loro cancellazione non crea problemi al normale funzionamento 

altrimenti si puo' usare il piu' pulito

apt-get clean

NumberFormatException da conversione in Numero di un campo EditText

asd


Stavo cercando di convertire i dati ripresi da una EditText in un numero a virgola mobile utilizzando il seguente comando


st = Double.parseDouble(txtportata.getText().toString());



Immancabilmente pero' il programma mi generava una eccezione del tipo

NumberFormatException

relativa al fatto che la stringa non poteva essere convertita in un numero (per esempio per la presenza di spazi o comunque di caratteri differenti da quelli numerici).
Per forzare l'utente ad introdurre solo valori numerici ho modificato la proprieta' InputType a NumberDecimale della EditText.
In questo modo pero' non sembrava possibile inserire il valore del punto decimale.

Impiegando l'emulatore si ha la tasteria numerica sotto riportata e cliccando sui caratteri speciali appare la barra in cui sono comprese il punto, la virgola ed altri


Purtroppo pero' questi caratteri non vengono accettati dalla EditText

Per far apparire il punto decimale si deve arrivare alla tastiera sotto riportata ed effettuare doppio clic sul pulsante che racchiude la virgola ed il punto



A questo punto non vengono piu' generate eccezioni ed la conversione funziona correttamente

venerdì 12 ottobre 2012

Zlib

La libreria Zlib permette la compressione con un metodo simile (ma non uguale all'algoritmo LZW) a quello dei file Zip

per la compilazione si deve utilizzare la stringa sottostante
gcc -Wall -O3 -lz zlib_test.c -o zlib_test

per comprimere i file si utilizza il seguente codice
-----------------------------------------------------
 FILE *infile = fopen(infilename, "rb");
gzFile outfile = gzopen(outfilename, "wb");

char inbuffer[128];
while ((num_read = fread(inbuffer, 1, sizeof(inbuffer), infile)) > 0) {
      gzwrite(outfile, inbuffer, num_read);
}
fclose(infile);
gzclose(outfile);

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

 mentre questo e' per decomprimere un file
-----------------------------------------------------
 gzFile infile = gzopen(infilename, "rb");
FILE *outfile = fopen(outfilename, "wb");

char buffer[128];
while ((num_read = gzread(infile, buffer, sizeof(buffer))) > 0) {
fwrite(buffer, 1, num_read, outfile);
}

gzclose(infile);
fclose(outfile);

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

Creare grafico (scatterplot) con AndroidPlot

Di seguito viene mostrato un esempio (sostanzialmente autoesplicativo nel codice) su come realizzare grafici ScatterPlot mediante la libreria AndroidPlot




activity_grafico.xml
-------------------------------------------------------------
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
   
    <com.androidplot.xy.XYPlot
        android:id="@+id/Grafico"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        title="Well Test" />

</RelativeLayout>

 -------------------------------------------------------------
Grafico.java
-------------------------------------------------------------
package com.luca.innocenti.well.test;

import java.util.Arrays;

import com.androidplot.series.XYSeries;
import com.androidplot.ui.AnchorPosition;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XLayoutStyle;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.YLayoutStyle;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;

public class Grafico extends Activity {

    private XYPlot Grafico;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_grafico);
        //inizializza il grafino
        Grafico = (XYPlot) findViewById(R.id.Grafico);
        //definisce le coppie di valori X (portata) ed Y (soggiacenza)
        Number[] portata = {0,1.0, 2, 3, 4, 5};
        Number[] soggiacenza = {0, -2, -4, -6, -8, -12};

       
        XYSeries dati = new SimpleXYSeries(Arrays.asList(portata),  Arrays.asList(soggiacenza), "Dati");

        // crea lo stile per i punti
        LineAndPointFormatter series1Format = new LineAndPointFormatter(
                Color.rgb(0, 200, 0),                   // line color
                Color.rgb(0, 100, 0),                   // point color
                null);                                  // fill color (none)

        // aggiunge i dati al grafico
        Grafico.addSeries(dati, series1Format);
 
        // AndroidPlot chiama Range l'asse X e Domain l'asse Y
        // riduce il numero di ticks su entrambi gli assi
        Grafico.setTicksPerRangeLabel(3);
        Grafico.setTicksPerDomainLabel(3);
       
        // mette il colore bianco in background
        Grafico.getGraphWidget().getGridBackgroundPaint().setColor(Color.WHITE);
        Grafico.getGraphWidget().setMarginTop(10);
       
        // cancella la legenda dal grafico
        Grafico.getLegendWidget().setVisible(false);
       
        //scrive le label sugli assi 
        Grafico.setDomainLabel("Portata");
        Grafico.getDomainLabelWidget().pack();
        Grafico.setRangeLabel("Soggiacenza");
        Grafico.getRangeLabelWidget().pack();

        Grafico.disableAllMarkup();
       
        Grafico.position(Grafico.getDomainLabelWidget(),0,XLayoutStyle.ABSOLUTE_FROM_CENTER,5, YLayoutStyle.ABSOLUTE_FROM_BOTTOM, AnchorPosition.CENTER);

       
        //Grafico.setGridPadding(15, 0, 15, 0);
    }
}

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

asd



martedì 9 ottobre 2012

Decomprimere DAA

Ho scaricato da Internet un file con estensione DAA e francamente non sapevo come usarlo
Dopo aver scoperto che e' sostanzialmente un file immagine (come un .iso) ho scaricato

apt-get install daa2iso

a questo punto ho convertito il file in iso

daa2iso file.daa file.iso

ed ho potuto leggere il contenuto dato che il gestore di archivi di Debian decomprime il formato iso

lunedì 8 ottobre 2012

Debian Testing in QEmu/Windows



Per prima cosa si deve creare una immagine disco (ho scelto 10 G dato che con l'installazione da 2G rimane decisamente poco spazio per qualunque operazione)

qemu-img.exe create deb.img 10G
Formating 'deb.img', fmt=raw, size=10485760 kB

stranamente utilizzando il comando
qemu-img.exe create deb.img 4G
viene generato un file da 0 Byte (con 3G o 5G tutto funziona correttamente)

per installare Debian partendo dal Cd di installazione con Xfce-Lxde si digita il seguente comando
qemu -localtime -m 256 -cdrom "debian-testing-i386-xfce+lxde-CD-1.iso" -hda deb.img -boot d -L . -net user -net nic

in questo modo si indicano
256 Mb di memoria
deb.img e' l'immagine del disco fisso
boot d fa partire l'installazione da CdRom
-net user -net nic abilita l'interfaccia di rete virtuale (questo e' l'unico sistema di abilitare la scheda di rete virtuale in ambiente in cui si e' amministratori del calcolatore)

Dato che il programma Qemu non e' installato ma il binario e' stato scompattato in una directory da un file zip e' necessario aggiungere lo swtich -L . (attenzione al punto)

Non e' stato possibile utilizzare KQemu perche' richiede l'installazione mentre sulla macchina su cui devo lavorare non possiedo i permessi di amministrazione

per utilizzare quindi la macchina virtuale una volta terminata l'installazione si deve effettuare lo shutdown e ripartire con
qemu -localtime -m 768 -cdrom "debian-testing-i386-xfce+lxde-CD-1.iso" -hda deb.img -boot c -L . -net user -net nic -redir tcp:2222::22

Per l'utilizzo normale la memoria e' stata impostata a 768 m ed e' stata aggiunta una direttiva per abilitare la connessione SSH tra Host e Guest sulla porta 2222

si puo' quindi usare sia SFTP che SSH chiamando la macchina virtuale a localhost:2222

Per finire la macchina virtuale assume un indirizzo derivante dal DHCP interno a QEMU  per cui risulta completamente invisibile all'esterno della macchina su cui e' in esecuzione (di solito l'IP e' 10.0.2.15)

Per terminare la finestra di visualizzazione massima e' 1024x768 e non puo' essere allargata a meno di modifiche piuttosto complicate al server X. Mettere QEmu in modalita' FullScreen e' stata una pessima esperienza sulla mia macchina dual-monitor e la sconsiglierei
 

Snippet : apici inversi in Bash

Una cosa che mi scordo regolarmente quando utilizzo bash ovvero come si crea il carattere apice rovescio su tastiere che ne sono sprovviste

La soluzione e' semplice

Alt Gr + apice diritto

Esempio con GUI con Zenity in shell Bash

Mentre stavo giocando con airoscript mi sono accorto di un script bash che mostrava delle simpatiche finestre di interfaccia; curiosando dentro il codice ho visto che il generatore delle finestre era Zenity, un programma studiato appositamente per rendere piu' interattiva la shell

Impiegando questo strumento e' stato possibile simulare un esempio di GUI da Bash
---------------------------------------------------------------
VALUE=`zenity --scale --text="Selezionare il valore" --value=0`

case $? in
    0)
        zenity --info --text="E'stato selezionato il valore $VALUE%"
        zenity --progress --title="Progress Bar" --text="Valore selezionato $VALUE%" --percentage=$VALUE;;
    1)
        zenity --error --text="Nessun valore selezionato";;
    -1)
        zenity --info --text="Errore non atteso";;
esac
---------------------------------------------------------------
Qui il link allo script



sabato 6 ottobre 2012

Webcam Logitech C310 su Debian Testing

Mi sono comprato la Logitech C310 perche' sembrava essere pienamente compatibile con Raspberry, cosa che in realta' si e' rivelata errata



In compenso la Webcam funziona in modo decisamente buono (se non ottimo) se paragonata alle altre Webcam dal costo di qualche euro inferiore
Le prove sono state effettuate nelle peggiori condizioni per una webcam ovvero in una stanza buia con la sola lampada della scrivania accesa ma la resa e' notevole

Screenshot da VLC



utilizzando FFMpeg invece si puo' usare la stringa (ripresa da qui)

ffmpeg -f alsa -ac 2 -ar 48000 -i hw:0,0 -acodec mp2 -f video4linux2  -r 30 -i /dev/video0 -vcodec mjpeg -sameq ffmpeg.avi

Per quanto riguarda Debian nella versione testing vengono riconosciuti correttamente sia la parte video che la  parte audio (microfono) ma il programma Cheese non riesce a funzionare correttamente (ha un ritardo veramente notevole)



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

mercoledì 3 ottobre 2012

Copiare Debian Live IMG su chiavetta USB



Per copiare i file scaricati da qui, dopo aver inserito la chiavetta USB, si deve digitare

dd if=debian-live-6.0.4-amd64-gnome-desktop.img of=/dev/sdb

ovviamente si deve vedere (mediante tail /var/log/messages dove si e' posizionata la chiavetta USB, in questo caso /dev/sdb)

Attenzione : il comando non ha un output per cui si deve attendere con pazienza fino a quando non si ritorna al prompt

GCC vs CLang vs ICC

Mi sono incuriosito del progetto LLVM/CLang ed ho voluto metterlo alla prova in confronto con Gcc e Icc utilizzando quanto gia' scritto in questo post

Immagine ripresa da Google Images



Di seguito i risultati
Gcc

real 0m1.613s
user 0m0.956s
sys 0m0.028s

Icc (Intel compiler)

real 0m1.064s
user 0m0.632s
sys 0m0.024s

CLang

real 0m0.983s
user 0m0.588s
sys 0m0.028s


In conclusione Gcc ne esce sempre con le ossa rotte ...c'e' da dire tuttavia che CLang e' un progetto piuttosto giovane e non permette di fare tutto cio' che e' possibile con Gcc



Hyperthreading e Open MP su Atom N450

Stavo pensando di iniziare a studiare la programmazione parallela quando mi sono accorto che tutte le mie macchine sono vecchiotte (ad esclusione del portatile di mia moglie che pero' e' intoccabile) e non sono provviste di un processore dual core. Avevo quasi abbandonato l'idea quando leggendo ho scoperto che il processore N450, pur essendo Single Core, possiede l'HyperThreading ovvero la capacita' di gestire piu' thread sul un solo core

Atom N450
Digitando il comando lscpu infatti si legge che

Architecture:  i686
CPU op-mode(s): 32-bit, 64-bit
CPU(s): 2
Thread(s) per core: 2
Core(s) per socket: 1
CPU socket(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 28
Stepping: 10
CPU MHz: 1662.438
L1d cache: 24K
L1i cache: 32K
L2 cache:  512K

Si vede chiaramente la presenza di un solo core ma i thread risultano due per cui e' possibile fare calcolo parallelo su N450
P4 640 3.2 GHz


Incuriosito mi sono chiesto se anche l'HP DC5100 SFF dotato di Pentium 4 Processor 640 with HT Technology  2.8 GHz poteva fare calcolo parallelo
Digitando lscpu e' apparso uno sconfortante

Architecture: i686
CPU op-mode(s):  32-bit, 64-bit
Byte Order:  Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 1
Vendor ID:  GenuineIntel
CPU family:  15
Model:  4
Stepping:  9
CPU MHz:  2793.347
BogoMIPS:  5586.69
L1d cache: 16K
L2 cache: 1024K

In un solo core con un solo thread?? Il problema e' stato risolto entrando nel BIOS ed abilitando lo switch dell'Hyperthreading. Una volta riavviata la macchina il risultato e' stato

Architecture:          i686
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    2
Core(s) per socket:    1
Socket(s):             1

Per testare l'effettivo utilizzo di HyperThreading ho usato il programma sotto riportato utilizzando OpenMP, una libreria per distribuire il calcolo

Il programma inizializza con il valore del seno un array molto grande, prima senza l'utilizzo di Hyperthreading e poi con

La prima prova, in modalita' standard, deve essere compilato con  g++ -Wall -O3 test_no.cpp -o test_no
---------------------------------------
#include <cmath>
#include <iostream>

using namespace std;

int main()
{
const int size = 100000;
double tabella[size];


for (int n=0; n<size;++n)
{
tabella[n] = sin(2*M_PI*n/size);
}
return 0;
}
---------------------------------------
La seconda, che utilizza invece OpenMP si compila con g++ -Wall -O3 test.cpp -o test -fopenmp
---------------------------------------
#include <cmath>
#include <omp.h>
#include <iostream>

using namespace std;

int main()
{
const int size = 100000;
double tabella[size];
int id;
int proc0,proc1;

#pragma omp parallel for
for (int n=0; n<size;++n)
{
id = omp_get_thread_num();
tabella[n] = sin(2*M_PI*n/size);
if (id == 1) proc1++;
else
proc0++;
}
cout << "0: "<< proc0 << "   |  1: "<<proc1;
return 0;
}
---------------------------------------
come si vede dall'output il carico di lavoro e' stato equamente diviso tra il thread 0 ed il thread 1 che hanno ciascuno effettutao 50000 cicli dei 100000 previsti
0: 50000   |  1: 50000

I tempi di caloolo sono pero' a favore della versione standard
Tempo con utilizzo dei thread
real 0m0.021s
user 0m0.020s
sys 0m0.012s

Tempo senza utilizzo dei thread
real 0m0.003s
user 0m0.000s
sys 0m0.004s

L'altra cosa divertente che ho scoperto e' che il mio Samsung N150 Plus esegue correttamente anche Debian a 64 Bit anche se,l leggendo qua e la', non ci sono particolari motivi di utilizzare 64 bit su una macchina con un solo Gb di Ram
Debian Live 64 Bit su N450 




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...