<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mind Unpacked</title>
	<atom:link href="http://mindunpacked.com/feed/?paged=3" rel="self" type="application/rss+xml" />
	<link>http://mindunpacked.com</link>
	<description>informatica.elettronica.chimica.new stuff</description>
	<lastBuildDate>Tue, 22 Dec 2009 17:35:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
<link>http://mindunpacked.com</link>
<url>http://mindunpacked.com/wp-content/plugins/maxblogpress-favicon/icons/favicon-2.ico</url>
<title>Mind Unpacked</title>
</image>
		<item>
		<title>Costruzione di un oscilloscopio analogico</title>
		<link>http://mindunpacked.com/2008/costruzione-di-un-oscilloscopio/</link>
		<comments>http://mindunpacked.com/2008/costruzione-di-un-oscilloscopio/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 20:47:32 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[analogico]]></category>
		<category><![CDATA[costruzione]]></category>
		<category><![CDATA[oscilloscopio]]></category>
		<category><![CDATA[schema]]></category>
		<category><![CDATA[transistor]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=204</guid>
		<description><![CDATA[Premessa
Prima di tutto va detto che in questo articolo non descriverò la costruzione di un moderno oscilloscopio, e non ne tratterò nemmeno la parte pratica. Lo scopo è quello di analizzare lo schema di un rudimentale oscillografo a transistor più che altro a scopo di studio. Comunque nessuno vieta, a chi lo volesse, di costruire [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm;"><strong>Premessa</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Prima di tutto va detto che in questo articolo non descriverò la costruzione di un moderno oscilloscopio, e non ne tratterò nemmeno la parte pratica. Lo scopo è quello di analizzare lo schema di un rudimentale oscillografo a transistor più che altro a scopo di studio. Comunque nessuno vieta, a chi lo volesse, di costruire realmente questo strumento, infatti posso garantire che se seguirete bene lo schema esso funzionerà senza troppi problemi. La pecca è che potrete misurare al massimo frequenze di 1 mhz, oltre ad essere monotraccia e ad essere privo &#8211; ovviamente – delle caratteristiche degli ultimi oscilloscopi digitali.</p>
<p style="margin-bottom: 0cm; text-align: justify;"><span id="more-204"></span></p>
<p style="margin-bottom: 0cm; text-align: justify;">L&#8217;oscillografo che andrò a descrivere è decisamente rudimentale, e le sue caratteristiche non sono certo al passo con i tempi, tuttavia è ottimo per arrivare a comprendere meglio come funziona questo utilissimo strumento di misura:<br />
Può effettuare misure da 3hz a 1 mhz (ma già qui si ha qualche perdita in db); Possibilità di trigger; Amplificatore anche per tensioni continue; Attenuatore con scala pretarata con una buona approssimazione; Amplificatore orizzontale (X) con fase identica a quello verticale (Y); Possibilità di essere alimentato sia in continua che in alternata. Si sa, inoltre, che per gli strumenti di misura è sempre necessaria un&#8217;alimentazione il più possibile stabile, e che non muti né in frequenza né in tensione. Per questo sarà presentato anche uno schema di un alimentatore sufficientemente stabile. Questo oscilloscopio utilizza un tubo a raggi catodici, anche perché non c&#8217;è proprio nulla di digitale in questo schema, e vi posso assicurare che schemi come questi, dove non ci sia neanche l&#8217;ombra di un integrato, sono davvero difficili da reperire al giorno d&#8217;oggi malgrado siano ottimi per scopi di studio.</p>
<p style="margin-bottom: 0cm;">Ma passiamo ad analizzare il circuito:</p>
<p style="margin-bottom: 0cm;"><strong>Gli schemi del progetto possono essere scaricati qui: </strong><a href="http://mindunpacked.com/risorse/schemi_oscilloscopio.pdf">schemi oscilloscopio</a></p>
<p style="margin-bottom: 0cm;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm;"><strong>Amplificatore verticale (Y)</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">L&#8217;amplificatore verticale è formato soltanto da due stadi amplificatori in controfase: questa soluzione è adottabile preferibilmente perché consente di ottenere un&#8217;ottima stabilità contro le variazioni di temperatura e dei parametri dei transistor. All&#8217;ingresso dell&#8217;amplificatore si trova un partitore di tensione tarato che, eventualmente, può essere compensato anche in frequenza, nel modo che citerò più avanti; l&#8217;impedenza di ingresso risulta costante per ciascuna posizione del commutatore ed ha un valore di 1 megaohm, compresa la sonda inserita nel puntale.</p>
<p style="margin-bottom: 0cm; text-align: justify;">A causa delle tensioni di lavoro relativamente elevate, le resistenze di carico del collettore sono alquanto elevate. Ad ogni modo l&#8217;amplificatore fornisce un&#8217;ottima risposta e quindi un buon guadagno fino alla frequenza di un megahertz. Nel circuito di ingresso di questo amplificatore è inserita una compensazione in corrente continua tarata per il valore di zero volt, per cui, cortocircuitando l&#8217;ingresso dell&#8217;amplificatore, la linea di riferimento della base dei tempi sullo schermo del tubo a raggi catodici rimane al centro dello schermo. L&#8217;amplificatore è insensibile alle variazioni di temperatura comprese tra i 10° C ed i 45° C. Quando lo strumento è alimentato con l&#8217;accumulatore (batteria), se la tensione di alimentazione dovesse diminuire, può darsi che la linea dello 0 sullo schermo del tubo si sposti: per ovvia a questo inconveniente si provvederà a regolare il potenziometro P5 (vedere schema) fino a riportare nelle normali posizioni la linea di riferimento.</p>
<p style="margin-bottom: 0cm;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm;"><strong>Amplificatore del trigger</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">L&#8217;esatto triggering è ottenuto mediante un circuito <a href="http://it.wikipedia.org/wiki/Trigger_di_Schmitt">trigger di Shmitt</a>. Questo circuito, come qualcuno saprà, ha l&#8217;inconveniente di richiedere all&#8217;ingresso tensioni elevate. Pertanto, per avere quest&#8217;impulso trigger di valore elevato, si usa un amplificatore sovrapilotato. Ogni volta che la somma risultante dal segnale e dall&#8217;impulso trigger, sulla base del transistor AC107, sorpassa lo zero, la tensione al collettore di questo transistor cambia. Il fianco di questo impulso di commutazione viene differenziato ed applicato alla base dei tempi. A motivo di questo particolare circuito triggering, il livello dell&#8217;impulso differenziato viene a dipendere dalla frequenza, per cui si rende necessario commutare contemporaneamente il condensatore differenziatore insieme a quelli della base dei tempi orizzontale.</p>
<p style="margin-bottom: 0cm;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm;"><strong>Generatore della base dei tempi orizzontale</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">La base dei tempi dell&#8217;oscilloscopio è formata da un circuito flip-flop monostabile, che riceve una reazione aggiuntiva attraverso l&#8217;emettitore. Mediante il potenziometro da 20 kohm (P7 nello schema), il circuito monostabile trigger si può regolare fino alla posizione astabile. Il punto di lavoro ottimo si trova poco prima della condizione di funzionamento auto-oscillante.</p>
<p style="margin-bottom: 0cm; text-align: justify;">La tensione a dente di sega viene prelevata dal condensatore che si trova nel circuito dell&#8217;emettitore. Il dente di sega viene portato all&#8217;amplificatore  orizzontale (X), attraverso uno stadio a collettore comune, con collettore a massa. Un altro transistor amplificatore produce una tensione rettangolare ricavata dalla base dei tempi con una ampiezza di ben 70 volt, che serve per la regolazione della luminosità del tubo a raggi catodici. Anche qui si richiede un transistor che possa sopportare un valore di tensione considerevole.</p>
<p><center><script type="text/javascript">
heyos_ad_user = 11334;
heyos_ad_type = "G";
heyos_ad_format = "1";
heyos_color_border = "23292b";
heyos_color_bg = "23292b";
heyos_color_link = "FFFFFF";
heyos_color_text = "21b8ca";
heyos_color_url = "21b8ca";
</script>
<script type="text/javascript" src="http://admaster.heyos.com/core/bnr.js"></script></center></p>
<p style="margin-bottom: 0cm;"><strong>Amplificatore orizzontale (X)</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">L&#8217;amplificatore orizzontale è formato da un solo stadio in controfase. Questo stadio è dimensionato più o meno come l&#8217;analogo stadio dell&#8217;amplificatore verticale. Si deve fare attenzione che le placchette di deflessione degli assi X ed Y abbiamo lo stesso valore di tensione, in modo da impedire, sullo schermo a raggi catodici, possibili distorsioni.</p>
<p style="margin-bottom: 0cm;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm;"><strong>Il tubo a raggi catodici e l&#8217;alimentazione</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Per la produzione delle varie tensioni di alimentazione degli amplificatori e del tubo a raggi catodici vengono impiegati due alimentatori, per cui è possibile adoperare lo strumento sia con una batteria che con la tensione di rete (230 v). Ovviamente i trasformatori – i cui dati verranno forniti in seguito &#8211; sono abbastanza particolari, e probabilmente sarà necessario crearseli da se o farseli avvolgere da qualche professionista. La frequenza di detti trasformatori non è la stessa: quella per la conversione CC/CA deve avere circa 40 khz, l&#8217;altra, quella per la rete luce, deve avere 50 hz.</p>
<p style="margin-bottom: 0cm; text-align: justify;">Nell&#8217; impiego ad accumulatore, nel caso questo iniziasse a scaricarsi, non soltanto vengono a diminuire le tensioni di alimentazione degli amplificatori (e quindi anche l&#8217;amplificazione), ma diminuisce contemporaneamente anche l&#8217;alta tensione. Questo, che a prima vista potrebbe sembrare un difetto, in effetti non lo è, poiché la sensibilità di deflessione del tubo catodico aumenta, per cui la diminuzione di amplificazione viene alquanto compensata da questo fatto. Così, per una variazione di tensione del 10% sull&#8217;accumulatore, non si ha nessuna perdita di guadagno o difetto di funzionamento. L&#8217;accumulatore dovrebbe essere da 6 volt, ed in grado di erogare 2 Ah.</p>
<p><center><div id="attachment_208" class="wp-caption aligncenter" style="width: 290px"><img class="size-full wp-image-208" title="Tubo a raggi catodici da 3&quot;" src="http://mindunpacked.com/wp-content/uploads/2008/12/dg3-12.jpg" alt="Tubo a raggi catodici da 3 pollici" width="280" height="114" /><p class="wp-caption-text">Tubo a raggi catodici </p></div></center></p>
<p style="margin-bottom: 0cm; text-align: justify;">Il tubo a raggi catodici più adatto a questo schema sarebbe uno non più grande di 3”, che possieda inoltre controlli di luminosità, fuoco ed astigmatismo. Questi controlli sono incredibilmente utili per uno strumento come l&#8217;oscilloscopio, e ne aumentano l&#8217;usabilità. L&#8217;accumulatore, invece, dovrebbe essere da 6 volt, ed in grado di erogare 2 Ah.</p>
<p style="margin-bottom: 0cm;"><strong>Trasformatore</strong></p>
<p style="margin-bottom: 0cm;">Per quanto concerne il trasformatore di alimentazione dirò che esso deve essere costituito dai seguenti avvolgimenti:</p>
<p style="margin-bottom: 0cm;">Primario:</p>
<p style="margin-bottom: 0cm;">2&#215;75 spire 0,3 (W1)</p>
<p style="margin-bottom: 0cm;">2&#215;40 spire 0,8 (W2)</p>
<p style="margin-bottom: 0cm;">Secondario:</p>
<p style="margin-bottom: 0cm;">36 spire 0,9 (W3)</p>
<p style="margin-bottom: 0cm;">120 spire 0,45 (W4)</p>
<p style="margin-bottom: 0cm;">685 spire 0,15 (W5)</p>
<p style="margin-bottom: 0cm;">Le tensioni al secondario dopo i duplicatori di tensione dovranno risultare con il carico accoppiato:</p>
<p style="margin-bottom: 0cm;">da W3 = +12 V e -12 V</p>
<p style="margin-bottom: 0cm;">da W4 = -70 V</p>
<p style="margin-bottom: 0cm;">da W5 = -500V</p>
<p style="margin-bottom: 0cm;">Per ottenere questi valori dovrete utilizzare un voltometro settato su 20 kohm per volt, misurando dalla massa.</p>
<p style="margin-bottom: 0cm;">Riguardo il trasformatore alimentato con la rete luce i valori sono i seguenti:</p>
<p style="margin-bottom: 0cm;">Primario:</p>
<p style="margin-bottom: 0cm;">Universale; potenza 40 Watt; frequenza 50 hz</p>
<p style="margin-bottom: 0cm;">Secondario:</p>
<p style="margin-bottom: 0cm;">6,3 V 1,2 A</p>
<p style="margin-bottom: 0cm;">35 V 300 mA</p>
<p style="margin-bottom: 0cm;">125 V 6 mA</p>
<p style="margin-bottom: 0cm;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm;"><strong>Funzione dei comandi</strong></p>
<p style="margin-bottom: 0cm;">Per finire vi illustro le funzioni dei vari interruttori e potenziometri.</p>
<p style="margin-bottom: 0cm;">SW1: Tensione CC o CA in entrata al canale Y</p>
<p style="margin-bottom: 0cm;">SW2: Rotazione di fase positiva o negativa</p>
<p style="margin-bottom: 0cm;">SW3: Sincronizzazione trigger interna od esterna</p>
<p style="margin-bottom: 0cm;">SW4: Entrata orizzontale interna od esterna</p>
<p style="margin-bottom: 0cm;">S1: Partitore di tensione con i seguenti valori: 100 mV; 300 mV; 1 V; 3 V; 10 V; 30 V; 100 V</p>
<p style="margin-bottom: 0cm;">S2: Tempi per la base dei tempi per i seguenti valori: 0,01 ms; 0,03 ms; 0,1 ms; 0,3 ms; 1 ms; 3 ms; 10 ms</p>
<p style="margin-bottom: 0cm;">S3: Interruttore di alimentazione (rete/spento/accumulatore)</p>
<p style="margin-bottom: 0cm;"><strong>Potenziometri:</strong></p>
<p style="margin-bottom: 0cm;">P5: Canale verticale, regolazione di posizione</p>
<p style="margin-bottom: 0cm;">P6: Scelta del livello trigger</p>
<p style="margin-bottom: 0cm;">P7: Regolazione della stabilità del trigger</p>
<p style="margin-bottom: 0cm;">P8: Regolazione unità dei tempi</p>
<p style="margin-bottom: 0cm;">P9: Regolazione di posizione del canale orizzontale</p>
<p style="margin-bottom: 0cm;">P10: Luminosità</p>
<p style="margin-bottom: 0cm;">P11: Fuoco</p>
<p style="margin-bottom: 0cm;">P12: astigmatismo</p>
<p style="margin-bottom: 0cm;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm;">Spero di avervi dato i giusti input per riuscire a comprendere al meglio i principi che stanno alla base di questo strumento di misura professionale, nonché adattabile ad innumerevoli campi applicativi.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/costruzione-di-un-oscilloscopio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TWM: Tab Window Manager</title>
		<link>http://mindunpacked.com/2008/twm-tab-window-manager/</link>
		<comments>http://mindunpacked.com/2008/twm-tab-window-manager/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 15:28:52 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[configurazione]]></category>
		<category><![CDATA[TWM]]></category>
		<category><![CDATA[window manager]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=190</guid>
		<description><![CDATA[Le interfacce grafiche straripanti di effetti grafici abbondano, e tra Windows Vista e Beryl i cicli macchina ormai si sprecano come il cibo. Fortunatamente c&#8217;è ancora gente che dopo aver esclamato “wow” si rende conto che il sistema è sì più attraente ma l&#8217;usabilità e la velocità sono dimezzate.
In questo articolo parlerò del noto – [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm; text-align: justify;">Le interfacce grafiche straripanti di effetti grafici abbondano, e tra Windows Vista e Beryl i cicli macchina ormai si sprecano come il cibo. Fortunatamente c&#8217;è ancora gente che dopo aver esclamato “wow” si rende conto che il sistema è sì più attraente ma l&#8217;usabilità e la velocità sono dimezzate.<br />
In questo articolo parlerò del noto – anche se non sono sicuro che sia poi così noto &#8211; <strong>window manager TWM</strong> (Tab Window Manager), in cui nutro parecchia simpatia. <span id="more-190"></span><br />
Ancora ai tempi in cui Xfree86 era a codice aperto questo window manager veniva distribuito assieme ad esso, ed ora che c&#8217;è <strong>X.Org</strong> la situazione non è cambiata. Lo trovate praticamente in tutte le distribuzioni linux che supportano X11, e probabilmente è il wm più veloce e leggero per sistemi unix. È molto semplice da configurare e può diventare estremamente produttivo facendo solo un po&#8217; di pratica.</p>
<p><center><div id="attachment_191" class="wp-caption aligncenter" style="width: 310px"><a href="http://mindunpacked.com/wp-content/uploads/2008/12/twm.gif"><img class="size-medium wp-image-191" title="twm" src="http://mindunpacked.com/wp-content/uploads/2008/12/twm-300x240.gif" alt="TWM - xterm ed emacs" width="300" height="240" /></a><p class="wp-caption-text">TWM - xterm ed emacs</p></div></center></p>
<p style="margin-bottom: 0cm;">Vediamo innanzitutto come avviarlo. Ovviamente do per scontato che abbiate già configurato il server X e vi funzioni tutto alla perfezione. Prendete il vostro file <strong>.xinitrc</strong> e modificatelo aggiungendo in una nuova riga:</p>
<p style="margin-bottom: 0cm;"><strong>twm</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">verificate che non siano segnati altri window manager onde evitare conflitti, quindi salvate il file.Prima di avviare la grafica è opportuno copiare il file di configurazione di TWM nella vostra home, così da avere una personalizzazione solo per il vostro utente. Il file si trova solitamente in <strong>/etc/X11/system.twmrc</strong>. Dovete copiarlo nella vostra home rinominandolo semplicemente .twmrc. È anche possibile rinominarlo <strong>.twmrc.&lt;nome_display&gt;</strong> per avere un file di configurazione diverso per ogni display X.<br />
<center><script type="text/javascript">
heyos_ad_user = 11334;
heyos_ad_type = "G";
heyos_ad_format = "1";
heyos_color_border = "23292b";
heyos_color_bg = "23292b";
heyos_color_link = "FFFFFF";
heyos_color_text = "21b8ca";
heyos_color_url = "21b8ca";
</script>
<script type="text/javascript" src="http://admaster.heyos.com/core/bnr.js"></script></center><br />
Prima di avviarlo, tuttavia,  è meglio verificare che nel menù di TWM ci sia un collegamento quantomeno ad un terminale, come xterm, altrimenti non potreste farci nulla:</p>
<pre class="brush: java;">
menu &quot;main&quot;
{
&quot;Main Menu&quot;		f.title
&quot;&quot;			f.nop
&quot;XTerm&quot;    f.exec  &quot;xterm &amp;amp;amp;amp;amp;amp;&quot;
&quot;Show Icon Manager&quot;	f.showiconmgr
&quot;Hide Icon Manager&quot;	f.hideiconmgr
&quot;&quot;			f.nop
&quot;Exit&quot;		f.menu &quot;Quit-Verify&quot;
}
</pre>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Come vedete si tratta di aggiungere un collegamento al terminale, ma questo solo nel caso che il file di configurazione non sia già stato modificato dalla vostra distribuzione. Molte versioni di linux, infatti, lo configurano in automatico, inserendo numerosi programmi nei sotto menù; tra poco vedremo comunque come aggiungere delle voci manualmente. Fatti gli opportuni cambiamenti al file di configurazione non vi resta che lanciare x:</p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT"><strong>$ startx</strong></p>
<p style="margin-bottom: 0cm;" lang="it-IT">il caricamento è pressoché immediato, e vi ritroverete davanti ad uno schermo completamente vuoto (sempre che non abbiate deciso di avviare dei programmi tramite .xinitrc. Per far apparire il menù basta cliccare in un punto qualsiasi con il tasto sinistro del mouse.<br />
Passiamo ora ad analizzare il file di configurazione. Sempre da TWM, usando il terminale, aprite il file .twmrc con un qualsiasi editor di testo. Potrete salvare i cambiamenti quando vorrete, e vi basterà riavviare TWM per vederli applicati in pochi secondi.</p>
<pre class="brush: java;">
NoGrabServer
RestartPreviousState
DecorateTransients
TitleFont &quot;-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*&quot;
ResizeFont &quot;-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*&quot;
MenuFont &quot;-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*&quot;
IconFont &quot;-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*&quot;
IconManagerFont &quot;-adobe-helvetica-bold-r-normal--*-100-*-*-*&quot;
#ClientBorderWidth

Color
{
BorderColor &quot;slategrey&quot;
DefaultBackground &quot;rgb:2/a/9&quot;
DefaultForeground &quot;gray85&quot;
TitleBackground &quot;rgb:2/a/9&quot;
TitleForeground &quot;white&quot;
MenuBackground &quot;rgb:2/a/9&quot;
MenuForeground &quot;gray85&quot;
MenuBorderColor &quot;slategrey&quot;
MenuTitleBackground &quot;gray70&quot;
MenuTitleForeground &quot;rgb:2/a/9&quot;
IconBackground &quot;rgb:2/a/9&quot;
IconForeground &quot;gray85&quot;
IconBorderColor &quot;gray85&quot;
IconManagerBackground &quot;azure&quot;
IconManagerForeground &quot;gray70&quot;
}
</pre>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">In questa prima parte si definiscono i vari font utilizzati dal wm, oltre che i colori delle varie parti. Per quest&#8217;ultimo punto i colori vanno scritti in RGB con notazione esadecimale, ciò significa che se avete un valore di blu pari a 162 dovrete scrivere a2. Da notare che è possibile personalizzare i colori per le diverse finestre:</p>
<pre class="brush: java;">
BorderColor  &quot;red&quot; { &quot;XTerm&quot; &quot;yellow&quot; }
</pre>
<p style="text-align: justify;">in questo caso settiamo il bordo delle finestre rosso, ma quello dell&#8217;xterm giallo. È possibile fare la stessa cosa con qualsiasi variabile.</p>
<p style="text-align: justify;">
<pre class="brush: java;">
#
# Define some useful functions for motion-based actions.
#
MoveDelta 3
Function &quot;move-or-lower&quot; { f.move f.deltastop f.lower }
Function &quot;move-or-raise&quot; { f.move f.deltastop f.raise }
Function &quot;move-or-iconify&quot; { f.move f.deltastop f.iconify }

#
# Set some useful bindings.  Sort of uwm-ish, sort of simple-button-ish
#
Button1 = : root : f.menu &quot;main&quot;
Button2 = : root : f.menu &quot;windowops&quot;

Button1 = m : window|icon : f.function &quot;move-or-lower&quot;
Button2 = m : window|icon : f.iconify
Button3 = m : window|icon : f.function &quot;move-or-raise&quot;

Button1 = : title : f.function &quot;move-or-raise&quot;
Button2 = : title : f.raiselower

Button1 = : icon : f.function &quot;move-or-iconify&quot;
Button2 = : icon : f.iconify

Button1 = : iconmgr : f.iconify
Button2 = : iconmgr : f.iconify
</pre>
<p style="margin-bottom: 0cm; text-align: justify;">Qui vengono prima definite delle funzioni per effettuare le classiche operazioni sulle finestre (sposta, ridimensiona, iconifica etc). Successivamente queste funzioni vengono associate ai diversi tasti del mouse. Anche qui potete cambiare quello che volete, invertire i pulsanti come più vi aggrada (il parametro “root” identifica la scrivania).</p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Veniamo ora alla parte forse più pratica ed utile del file di configurazione, ovvero le strutture dei menù.</p>
<pre class="brush: java;">
menu &quot;main&quot;
{
&quot;Main Menu&quot;		f.title
&quot;&quot;			f.nop
&quot;Show Icon Manager&quot;	f.showiconmgr
&quot;Hide Icon Manager&quot;	f.hideiconmgr
&quot;&quot;			f.nop
&quot;Exit&quot;			f.menu &quot;Quit-Verify&quot;
}

menu &quot;Quit-Verify&quot;
{
&quot;Really quit twm?&quot;	f.title
&quot;No, restart twm&quot;	f.restart
&quot;Yes, really quit&quot;	f.quit
}

menu &quot;windowops&quot;
{
&quot;Window Ops&quot;		f.title
&quot;&quot;			f.nop
&quot;Iconify&quot;		f.iconify
&quot;Resize&quot;		f.resize
&quot;Move&quot;			f.move
&quot;Raise&quot;			f.raise
&quot;Lower&quot;			f.lower
&quot;&quot;			f.nop
&quot;Focus&quot;			f.focus
&quot;Unfocus&quot;		f.unfocus
&quot;&quot;			f.nop
&quot;Delete&quot;		f.delete
&quot;Destroy&quot;		f.destroy
}
</pre>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Queste righe sono quelle che probabilmente troverete anche nel vostro file .twmrc, e sono quelle standard che non comprendono nessun collegamento a nessuna applicazione, né dei sotto menù. Per creare una categoria nel main vi basta inserire una riga di questo genere:</p>
<pre class="brush: java;">
&quot;Linux&quot;		f.menu &quot;/Linux&quot;
</pre>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">In questo modo avrete un primo livello di menù con etichetta “Linux”, a cui potrete aggiungere quante voci vorrete:</p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">
<pre class="brush: java;">
menu &quot;/Linux/Aiuto&quot;
{
&quot;APT HOWTO&quot;    f.exec  &quot;/usr/bin/apt-howto &amp;amp;amp;amp;amp;&quot;
}
menu &quot;/Linux/Applicazioni&quot;
{
...
}
</pre>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Abbiamo così aggiunto due sotto menù alla voce Linux, precisamente Aiuto ed Applicazioni. Tra le parentesi graffe potete aggiungere qualsiasi tipo di collegamento usando la sintassi della riga 3. In questo modo potete costruirvi una rete anche ampia di categorie con le rispettive applicazioni, ottenendo un menù di tutto rispetto.<br />
Sono presenti molte altre variabili, ma per il loro utilizzo vi consiglio di dare un&#8217;occhiata alla <a href="http://linux.die.net/man/1/twm">pagina man di twm</a>. Vorrei invece concludere descrivendo le opzioni che si possono aggiungere al comando twm:</p>
<p style="margin-bottom: 0cm;" lang="it-IT"><strong>-display &lt;num_display&gt;</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Vi permette di avviare TWM su un display X a vostra scelta tra quelli precedentemente avviati</p>
<p style="margin-bottom: 0cm;" lang="it-IT"><strong>-f &lt;filename&gt;</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Potete specificare il nome del file di configurazione che twm dovrà utilizzare. Normalmente controlla il file .twmrc nella vostra home, oppure quello di sistema syestem.twmrc</p>
<p style="margin-bottom: 0cm;" lang="it-IT"><strong>-v</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Questa è una sorta di “verbose mode”, e farà sì che twm stampi a schermo gli eventuali errori che il server X produce. È utile più che altro per sessioni di debugging.</p>
<p style="margin-bottom: 0cm; text-align: justify;" lang="it-IT">Spero di avervi descritto sufficientemente bene l&#8217;utilizzo di questo window manager da “fanatici”, il quale vi permetterà di immergervi completamente in qualsiasi operazione, privati una volta per tutte da qualsivoglia distrazione frivola.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/twm-tab-window-manager/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Un nuovo metodo per visualizzare l&#8217;insieme di Mandelbrot: il Buddhabrot.</title>
		<link>http://mindunpacked.com/2008/un-nuovo-metodo-per-visualizzare-linsieme-di-mandelbrot-il-buddhabrot/</link>
		<comments>http://mindunpacked.com/2008/un-nuovo-metodo-per-visualizzare-linsieme-di-mandelbrot-il-buddhabrot/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 23:25:58 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Buddhabrot]]></category>
		<category><![CDATA[Frattali]]></category>
		<category><![CDATA[Mandelbrot]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=116</guid>
		<description><![CDATA[Chi si interessa di matematica avrà sicuramente sentito parlare di quelle meravigliose figure che sono i frattali. In questo articolo vi parlerò di un metodo particolare, chiamato Buddhabrot, per visualizzare l&#8217;insieme di Mandelbrot che è uno dei frattali più famosi. Per questo motivo darò per scontati alcuni concetti di base e anche la conoscenza dell&#8217;insieme [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Chi si interessa di matematica avrà sicuramente sentito parlare di quelle meravigliose figure che sono i frattali. In questo articolo vi parlerò di un metodo particolare, chiamato Buddhabrot, per visualizzare l&#8217;<strong>insieme di Mandelbrot</strong> che è uno dei frattali più famosi. Per questo motivo darò per scontati alcuni concetti di base e anche la conoscenza dell&#8217;insieme di Mandelbrot. L&#8217;articolo sarà corredato dal codice di un programma in C++, che è lo stesso che ho usato per renderizzare le immagini presenti in questo articolo.<br />
<span id="more-116"></span><br />
Il <strong>Buddhabrot</strong> è una tecnica speciale inventata da <a title="Pagina del Buddhabrot di Melina Green" href="http://www.superliminal.com/fractals/bbrot/bbrot.htm" target="_blank">Melinda Green</a> che porta a dei risultati davvero spettacolari. Per disegnare l&#8217;insieme di Mandelbrot si analizzano vari punti del piano e si considerano appartenenti all&#8217;insieme quelli che <strong>non divergono</strong> (cioè non tendono ad allontanarsi ad una distanza infinita dall&#8217;origine) quando gli viene applicata ripetutamente la formula Z<sub>n+1</sub> = Z<sub>n</sub><sup>2</sup> + C. Nella formula C è un numero complesso che rappresenta le coordinate del punto che stiamo analizzando, e si parte da Z<sub>0</sub> = 0. La tecnica inventata da Melinda Green, invece, tiene in considerazione non la divergenza o meno di un punto ma la traiettoria descritta dai punti che <strong>divergono</strong> quando gli viene applicata ripetutamente la formula. Tutti i punti del piano descriveranno diverse traiettorie, così ci saranno zone meno trafficate e zone più trafficate, le prime risulteranno più scure e le ultime più luminose. Se, invece di considerare le traiettorie dei punti che divergono considerassimo quelle dei punti che non divergono otterremo il cosidetto Anti-Buddhabrot.</p>
<p style="text-align: justify;">Quando si renderizza l&#8217;insieme di Mandelbrot l&#8217;appartenenza di un punto all&#8217;insieme viene stabilita in base alla divergenza dello stesso. Per testare la divergenza viene applicata la formula su di esso diverse volte e, se il punto non accenna a divergere dopo un determinato numero di iterazioni (detto <strong>bailout</strong>) il punto viene considerato appartenente all&#8217;insieme. Chiaramente questo è scorretto dal punto di vista teorico, perchè si dovrebbe verificare che un punto non diverge quando il bailout tende all&#8217;infinito, ma visto che non è possibile effettuare un numero infinito di iterazioni ci si accontenta di un valore di bailout abbastanza alto che consente una notevole approssimazione. Ah, un punto viene considerato divergente quando la sua distanza dall&#8217;origine diventa maggiore di 2.</p>
<p style="text-align: justify;">Quando il bailout è abbastanza alto i risultati che otterremo saranno più precisi. Anche se il bailout è relativamente trascurabile per l&#8217;insieme di <strong>Mandelbrot</strong> (con valori abbastanza alti non si nota la differenza tra un valore ed un altro a meno che non stiamo zoomando), esso diviene fondamentale per renderizzare il Buddhabrot, ecco due immagini con valori di bailout diversi:</p>
<table style="text-align: justify;" border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_129" class="wp-caption alignnone" style="width: 310px"><a href="http://mindunpacked.com/wp-content/uploads/2008/11/1.jpg"><img class="size-medium wp-image-129" title="Buddhabrot N=20" src="http://mindunpacked.com/wp-content/uploads/2008/11/1-300x300.jpg" alt="Buddhabrot N=20" width="300" height="300" /></a><p class="wp-caption-text">Buddhabrot N=20</p></div></td>
<td>
<p><div id="attachment_131" class="wp-caption alignnone" style="width: 310px"><a href="http://mindunpacked.com/wp-content/uploads/2008/11/2.jpg"><img class="size-medium wp-image-131" title="Buddhabrot N=200" src="http://mindunpacked.com/wp-content/uploads/2008/11/2-300x300.jpg" alt="Buddhabrot N=200" width="300" height="300" /></a><p class="wp-caption-text">Buddhabrot N=200</p></div></td>
</tr>
</tbody>
</table>
<p style="text-align: justify;"><!--adsense--><br />
I parametri che concorrono a determinare la qualità dei nostri rendering sono i seguenti:</p>
<ul style="text-align: justify;">
<li><strong>bailout</strong>: come abbiamo appena detto, più il bailout è elevato e minore sarà il margine di errore che potremmo avere su ogni punto. Per esempio, ci sono punti che divergono molto lentamente e che con un bailout basso vengono considerati non divergenti.</li>
</ul>
<ul style="text-align: justify;">
<li><strong> numero di pixels esaminati</strong>: di più pixels esaminiamo le traiettorie e più nitida sarà la nostra immagine. Quando il numero di pixels non è sufficiente otteniamo un fastidioso &#8220;effetto griglia&#8221;.</li>
</ul>
<ul style="text-align: justify;">
<li><strong> risoluzione</strong>: ovviamente, più è alta la risoluzione è migliore sarà la nostra immagine. C&#8217;è da notare, però, che immagini a risoluzione più alta richiedono un numero di pixels esaminati maggiore per ottenere risultati buoni, rispetto a immagini con risoluzione minore.</li>
</ul>
<p style="text-align: justify;">I tempi di rendering per questo tipo di frattale sono piuttosto lunghi, e quando i parametri qualitativi sono elevati diventano quasi insopportabili.</p>
<p style="text-align: justify;">Le immagini che abbiamo visto fino ad ora sono tutte in bianco e nero. Per ottenere risultati a colori viene usata una tecnica simile a quella che la NASA usa per <a title="Come la NASA colora le immagini" href="http://hubblesite.org/sci.d.tech/behind_the_pictures/meaning_of_color/index.shtml" target="_blank">colorare le immagini astronomiche</a>, cioè i <a title="Falsi colori, Wikipedia" href="http://en.wikipedia.org/wiki/False-color" target="_blank">falsi colori</a>. Così come la NASA assegna un colore diverso ad ogni frequenza della luce che riceve dallo spazio, noi creiamo tre immagini in bianco e nero con diversi valori di bailout e le assegnamo rispettivamente ai canali R, G e B dell&#8217;immagine. Otterremo in questa maniera immagini simili alle seguenti:</p>
<table style="text-align: justify;" border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_181" class="wp-caption alignnone" style="width: 310px"><a href="http://mindunpacked.com/wp-content/uploads/2008/12/3.jpg"><img class="size-medium wp-image-181" title="Buddahbrot 1" src="http://mindunpacked.com/wp-content/uploads/2008/12/3-300x300.jpg" alt="" width="300" height="300" /></a><p class="wp-caption-text">valore di bailout = 500, risoluzione = 1024x1024, tempo di rendering 50 minuti</p></div></td>
<td>
<p><div id="attachment_182" class="wp-caption alignnone" style="width: 310px"><a href="http://mindunpacked.com/wp-content/uploads/2008/12/davebrotmy6.jpg"><img class="size-medium wp-image-182" title="Buddahbrot" src="http://mindunpacked.com/wp-content/uploads/2008/12/davebrotmy6-300x300.jpg" alt="" width="300" height="300" /></a><p class="wp-caption-text">I dati di questa immagine non li ricordo... spero mi perdoniate.</p></div></td>
</tr>
</tbody>
</table>
<p style="text-align: justify;">(Nota: i colori dell&#8217;ultima immagine sono stati leggermente ritoccati con Photoshop)</p>
<p style="text-align: justify;">Bene, per ora è tutto. Spero di scrivere un secondo articolo su questo argomento in cui descriverò un&#8217;altra tecnica per renderizzare animazioni con il Buddhabrot (che in realtà può essere immaginato come un oggetti in 4 dimensioni), ma siccome i tempi di rendering sono piuttosto lunghi, dovrete aspettare che finisca di renderizzare un bel video. Allego qui il file sorgente del programma che ho usato per realizzare i rendering: <a title="Buddhabrot C++" href="http://www.mindunpacked.com/risorse/buddhabrot.tar.gz" target="_self">Buddhabrot C++</a></p>
<p style="text-align: justify;">Alla prossima&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/un-nuovo-metodo-per-visualizzare-linsieme-di-mandelbrot-il-buddhabrot/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ALD-52</title>
		<link>http://mindunpacked.com/2008/ald-52/</link>
		<comments>http://mindunpacked.com/2008/ald-52/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 13:43:29 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Chimica]]></category>
		<category><![CDATA[ALD-52]]></category>
		<category><![CDATA[LSD-25]]></category>
		<category><![CDATA[Orange Sunshine]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=124</guid>
		<description><![CDATA[




Praticamente tutti conoscono la famosa scoperta di Albert Hofmann, ovvero l’LSD-25. Successivamente alla sua scoperta si fecero numerosi studi a riguardo, e si riuscirono a trovare molti altri suoi analoghi che mantengono il gruppo dietilamide invariato. Alcune ammine dell’acido lisergico sono: Ergonovina, Metilergonovina, LAE-32, MLD-41, DAM-57, CYP-LAD, BOL-148, LSM-775, ALD-52. Tutte queste molecole sono psicoattive, [...]]]></description>
			<content:encoded><![CDATA[<table style="height: 216px;" border="0" cellspacing="0" cellpadding="0" width="625">
<tbody>
<tr>
<td style="padding-left: 30px;"><img class="aligncenter" title="ALD-52 molecola animata" src="http://mindunpacked.com/risorse/ald52.gif" alt="" width="200" height="200" /></td>
<td>
<p style="text-align: justify; padding-left: 30px;">Praticamente tutti conoscono la famosa scoperta di <strong>Albert Hofmann</strong>, ovvero l’<strong>LSD-25</strong>. Successivamente alla sua scoperta si fecero numerosi studi a riguardo, e si riuscirono a trovare molti altri suoi analoghi che mantengono il gruppo dietilamide invariato. Alcune ammine dell’acido lisergico sono: Ergonovina, Metilergonovina, LAE-32, MLD-41, DAM-57, CYP-LAD, BOL-148, LSM-775, ALD-52. Tutte queste molecole sono psicoattive, ed in particolare l’ultima menzionata è quella su cui mi soffermerò. L’ALD-52 o anche N-acetil-LSD, è un isomero di struttura dell’LSD. Questo significa che la formula molecolare tre le due è la medesima, ma a cambiare è la formula di struttura.</p>
</td>
</tr>
</tbody>
</table>
<p><span id="more-124"></span></p>
<p style="text-align: justify;">Questo isomero mantiene molte delle caratteristiche proprie dell’LSD, prima fra tutte la capacità di provocare allucinazioni medio/forti. Oltre a questo aspetto in comune, l’ALD-52 sembrerebbe provocare molta meno ansia o stress psicologico durante il trip, e la pressione sanguinia tende ad aumentare maggiormente. Tuttavia a parità di dosi l’<strong>effetto sul sistema nervoso è minore</strong>.</p>
<p style="text-align: justify;">Questa molecola venne sintetizzata intorno agli anni 60 dallo stesso Albert Hofmann, e successivamente venne imitato da numerosissimi laboratori clandestini, che sintetizzandolo potevano avere una valida alternativa all&#8217;LSD completamente legale. Proprio per questo girò per moltissimo tempo e prese il nome di  <strong>Orange Sunshine</strong>. Questo spiegherebbe le voci che affermano che a quei tempi se ne assumesse molta di più (500-600 microgrammi contro gli 80/100 di oggi). In realtà tutt&#8217;ora di ALD-52 se ne trova davvero poca, e probabilmente il costo di produzione dell&#8217;LSD è minore – oltre al fatto che ora è anch&#8217;essa illegale -, quindi di conseguenza sono sufficienti piccole dosi per ottenere anche effetti piuttosto pesanti.<br />
L&#8217;ALD-52 è tuttavia molto instabile, e se esposta a troppa luce od umidità, muta velocemente in LSD. Come detto precedentemente questa sostanza o viene sintetizzata per motivi legali – in quei paesi ove la legge non sia sia ancora adeguata -, oppure per ricercare un trip simile a quello provocato dell&#8217;LSD ma con meno effetti indesiderati. Inoltre i noti flashback allucinatori dell&#8217;LSD non sembrano manifestarsi dopo l&#8217;assunzione di questa ammina, ed anche i post-effetti sono meno intensi di quelli della “molecola madre”.</p>
<p style="text-align: justify;">Il processo per produrre L&#8217;ALD-52 prevede di partire dall&#8217;LSD, questo almeno fino a poco tempo fa. Nel 2004 infatti è stato scoperto un procedimento diverso per sintetizzare l&#8217;acido lisergico, con il quale è possibile ottenere direttamente l&#8217;ALD-52 senza passare forzatamente dall&#8217;LSD base. Per chi fosse interessato il procedimento viene illustrato qui (in inglese):<a href="http://mindunpacked.com/risorse/A_New_Synthesis_of_Lysergic_Acid.pdf"> A New Synthesis of Lysergic Acid</a> In ogni caso il procedimento non è dei più semplici.</p>
<p style="text-align: justify;">Spero di avervi chiarito abbastanza le idee a proposito di questa ammina parente dell&#8217;LSD, forse troppo sconosciuta malgrado le sue interessanti caratteristiche&#8230;</p>
<p><!--adsense--></p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/ald-52/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reti neurali attraverso algoritmi genetici in C++. Parte III</title>
		<link>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iii/</link>
		<comments>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iii/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 22:14:33 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Algoritmi genetici]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Intelligenza artificiale]]></category>
		<category><![CDATA[Reti neurali]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=132</guid>
		<description><![CDATA[IMPLEMENTAZIONE
Ok, siamo arrivati alla parte più tecnica cioè all&#8217;implementazione vera e propria della rete. Ho scelto di utilizzare il C++ e di programmare tutto ad oggetti perchè, anche se questo approccio sacrifica forse un po&#8217; la velocità, rende, almeno per me, il tutto più comprensibile e riutilizzabile (dalle classi che qui espongo ho costruito poi [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>IMPLEMENTAZIONE</strong></p>
<p align="justify">Ok, siamo arrivati alla parte più tecnica cioè all&#8217;implementazione vera e propria della rete. Ho scelto di utilizzare il C++ e di programmare tutto ad oggetti perchè, anche se questo approccio sacrifica forse un po&#8217; la velocità, rende, almeno per me, il tutto più comprensibile e riutilizzabile (dalle classi che qui espongo ho costruito poi una libreria per l&#8217;utilizzo delle reti neurali).</p>
<p><span id="more-132"></span></p>
<p align="justify">Cominciamo a partire dalle classi della rete neurale.</p>
<p align="center"><strong>Le classi Neuron, NeuronLayer e NeuralNet </strong></p>
<p align="justify">La prima classe che implementeremo è la classe <strong>Neuron</strong>, che rappresenta la struttura più piccola della rete neurale: il neurone.</p>
<p align="justify">Ogni neurone come abbiamo visto ha dei collegamenti pesati in entrata (tranne i neuroni di input) e un valore, che è contiene il valore del neurone.</p>
<p align="justify">Il codice della classe Neuron è il seguente:</p>
<pre class="brush: cpp;">
class Neuron {
	public:
		Neuron(int c_numWeights);
		void setValue(double v);
		double getValue() const;
		void setWeight(int i, double v);
		double getWeight(int i) const;
		int getWeightsNum(bool bias) const;
	private:
		double value;
		vector&lt;double&gt; weights;
};
</pre>
<p>I metodi di questa classe sono tutti molto facili da capire: riporto qui solamente il codice del costrutture e di getWeightsNum(bool):</p>
<pre class="brush: cpp;">
// Costruttore
Neuron::Neuron(int c_numWeights) {
	for (int i = 0; i &lt; c_numWeights+1; i++) {
		weights.push_back(wRand());
	}
}
int Neuron::getWeightsNum(bool bias) const {
	return (bias) ? weights.size() : weights.size() 1;
}
</pre>
<p align="justify">Il costruttore riceve come argomento il numero dei pesi in entrata per questo neurone e li inizializza a valori random (wRand() è una funzione definita in un file header che restituisce un numero compreso tra -1 e 1). Se osservate bene il ciclo va da 0 a c_numWeights+1 questo perchè viene creato un peso aggiuntivo chiamato bias, la cui funzione vi sarà chiara fra poco.</p>
<p align="justify">Nella classe Neuron avremmo potuto anche creare un puntatore a funzione che puntasse alla funzione di attivazione (o funzione di trasferimento) del neurone ed in questa maniera avremmo potuto impostare una funzione di attivazione diversa per ogni neurone (o per ogni livello), ma visto che la nostra funzione sarà uguale per tutti i neuroni, ho preferito non farlo per questioni di semplicità.</p>
<p align="justify">E&#8217; arrivato il momento di spendere due parole proprio sulle funzioni di attivazione. La <strong>funzione di attivazione</strong> può essere una qualunque funzione, come per esempio , ma alcune offrono risultati migliori in base al contesto nella quale sono utilizzate. Scegliere la funzione giusta può essere determinante per ottenere buoni risultati.</p>
<p align="justify">Vediamo alcune funzioni comunemente usate:</p>
<p align="justify">
<p align="justify"><strong>Funzione a gradino: y = 1 per x &gt;= 0, 0 per x &lt; 0</strong></p>
<p align="justify">La funzione a gradino (chiamata così per il suo grafico) è la funzione che più rispetta il comportamento del <strong>neurone biologico</strong>. Infatti essa restituisce 1, cioè propaga il segnale, se la somma degli input ricevuti e maggiore o uguale a un certo numero , che altro non è che la soglia di attivazione. E&#8217; utile utilizzare questa funzione quando vogliamo che la nostra rete abbia un risultato che o 1 o 0 e che quindi separi gli input che gli forniamo in due classi distinte.</p>
<p align="justify">
<p align="justify"><span style="color: #808080;"><strong>Funzione identità: y = x</strong></span></p>
<p align="justify">Non penso ci sia molto da dire su questa funzione, l&#8217;unica cosa da sapere è che si utilizza quando il nostro output non è limitato e può variare da meno infinito a più infinito.</p>
<p align="justify">
<p align="justify"><strong>Funzione sigmoidale: y = 1/(1+e^(-x)) </strong></p>
<p align="justify">
<p align="justify">La funzione sigmoidale è una delle funzioni più utilizzate. Essa passa sempre per il punto (0, 1/2) ed è compresa tra 0 e 1. Proprio per quest&#8217;ultimo fatto non può essere utilizzata se ci aspettiamo come output numeri numeri che non sono compresi in questo intervallo, per i quali è necessario utilizzare altre funzioni.</p>
<p align="justify">
<p align="justify">
<p align="justify"><strong>Tangente iperbolica: y = tanh(x)</strong></p>
<p align="justify">La tangente iperbolica è molto simile alla funzione sigmoidale solo che il suo output è compreso tra -1 e 1 e passa sempre per l&#8217;origine. Come al solito va utilizzata solo nei casi in cui l&#8217;output deve essere compreso tra questi valori e per esempio non andrebbe bene se volessimo allenare la rete a fare la somma di due numeri qualsiasi. In realtà le cose non stanno esattamente così, perchè, come vedremo in seguito, esiste un apposito valore (bias) per ogni neurone che serve a spostare il centro della funzione e quindi ad ottenere valori che non sono più compresi tra -1 e 1 ma tra meno infinito  e  più infinito.</p>
<p align="justify">In ogni caso è comunque preferibile una funzione di trasferimento lineare nei casi in cui il nostro output possa variare in maniera illimitata.</p>
<p align="justify">
<p><!--adsense--></p>
<p align="justify">Dopo questa parentesi a proposito delle <strong>funzioni di attivazion</strong>e torniamo alla nostra implementazione. Una volta che il neurone fa la sommatoria pesata di tutti gli input ricevuti passa questo valore alla funzione di attivazione che, a sua volta, restituisce un altro valore. Quest&#8217;ultimo sarà propagato ai neuroni successivi e così via.</p>
<p align="justify">La seconda classe di cui ci occuperemo è NeuronLayer, che rappresenta uno strato di neuroni:</p>
<p align="justify">
<pre class="brush: cpp;">
class NeuronLayer {
	public:
		NeuronLayer(int c_numNeurons, int c_weightsPerNeuron);
		Neuron* getNeuron(int i) const;
		int getNeuronsNum() const;
	private:
		vector&lt;Neuron*&gt; neurons;
};
</pre>
<p align="justify">
<p align="justify">Come è logico, la classe <strong>NeuronLayer</strong> dovrà contenere un insieme di neuroni e per questo usiamo la classe vector della STL per istanziare un vettore di oggetti Neuron*.</p>
<p align="justify">Anche qui i metodi sono abbastanza semplici: il costruttore riceve come parametri il numero dei neuroni facenti parte del layer ed il numero di collegamenti in entrata (e quindi di pesi) per ogni neurone. La funzione getNeuron(int) riceve come parametro un intero i e restituisce l&#8217;i-esimo neurone del livello; l&#8217;ultima funzione restituisce il numero totale dei neuroni facenti parti del livello.</p>
<p align="justify">
<p align="justify">Siamo giunti alla parte cruciale del nostro programma e cioè la classe NeuralNet.</p>
<p align="justify">Sarà lei che si occuperà di collegare i neuroni fra di loro, di propagare i segnali attraverso i neuroni e di darci l&#8217;output restituito dalla rete.</p>
<p align="justify">
<pre class="brush: cpp;">
class NeuralNet {
	public:
		NeuralNet(int c_numInputNeurons, int c_numOutputNeurons,
		int c_numHiddenLayers, int c_numNeuronsPerLayer);
		void createNet();
		void run(vector&lt;double&gt; input, Chromosome* d);
		int totalNumWeights(bool bias);
		void dump();
		double globalError(vector&lt;double&gt; des);
		void printOutput();
	private:
		vector&lt;NeuronLayer*&gt; layers;
		int numInputNeurons,
		numOutputNeurons,
		numHiddenLayers,
		numNeuronsPerLayer;
}
</pre>
<p align="justify">
<p align="justify">Il costruttore della classe <strong>NeuralNet</strong> riceve in input 4 parametri che sono rispettivamente il numero dei neuroni di input, il numero dei neuroni di output, il numero dei livelli nascosti e il numero di neuroni contenuti nei livelli nascosti.</p>
<p align="justify">Il costruttore non fa altro che prendere questi argomenti e salvarli nelle quattro variabili apposite. Il vettore layers contiene dei puntatori ad oggetti NeuronLayer che saranno appunto i vari livelli della rete neurale. Due sono i metodi più importanti di questa classe: createNet() e run(vector&lt;double&gt;, Chromosome*). Il primo inizializza l&#8217;array layers creando i livelli necessari ed i collegamenti tra i vari neuroni, mentre il secondo, esegue la rete neurale passandogli in input i valori contenuti nell&#8217;array input ed utilizzando come pesi della rete il DNA dell&#8217;oggeto Chromosome*. Vediamo il codice di queste due funzioni:</p>
<pre class="brush: cpp;">
void NeuralNet::createNet() {
	if (numHiddenLayers &gt; 0) {
		// Se ci sono layer nascosti li crea
		NeuronLayer* HL = new NeuronLayer(numNeuronsPerLayer,
							numInputNeurons);
		layers.push_back(HL);
		for (int i = 1; i &lt; numHiddenLayers; i++) {
			NeuronLayer* HL = new NeuronLayer(numNeuronsPerLayer,
								numNeuronsPerLayer);
			layers.push_back(HL);
		}
		NeuronLayer* OL = new NeuronLayer(numOutputNeurons,
							numNeuronsPerLayer);
		layers.push_back(OL);
	} else {
		NeuronLayer* OL = new NeuronLayer(numOutputNeurons,
							numInputNeurons);
		layers.push_back(OL);
	}
}
</pre>
<p align="justify">La prima cosa che la funzione fa è quella di verificare se deve creare dei <strong>layer nascosti</strong> o meno. Nel primo caso crea il primo layer nacosto in cui ogni neurone ha un numero di pesi pari al numero dei neuroni in input (infatti i neuroni del primo layer ricevono i dati proprio dai neuroni di input)  e crea i layer seguenti in cui ogni neurone ha un numero di pesi pari al numero di neuroni presenti negli strati precedenti a lui, che essendo tutti strati nascosti avranno un numero di neuroni pari al contenuto della variabile numNeuronsPerLayer; come ultima cosa viene creato il layer di output. Se non ci sono layer nascosto la prima parte viene saltata e viene creato un layer di output collegato direttamente a quello di input.</p>
<p><!--adsense--></p>
<p align="justify">La funzione run() è un po più complessa. Ho evitato di scriverla tutta qui per problemi di impagnazione, quindi vi conviene leggerla direttamente dal file sorgente. Comunque, la prima cosa che la funziona fa è controllare che il numero degli input ricevuti dalla funzione corrisponda effettivamente al numero di neuroni di input: se così non è l&#8217;esecuzione del programma termina dopo aver stampato un messaggio di errore.</p>
<p align="justify">Successivamente la funzione deve impostare i pesi della rete neurale con il DNA del <strong>cromosoma</strong> che gli passiamo come argomento, per fare questo si utilizzano tre cicli for annidati: il primo scorre tutti i livelli della rete neurale, il secondo tutti i neuroni di ogni livello ed il terzo tutti i pesi di ogni neurone, sosituendoli con quelli presenti nel cromosoma.</p>
<p align="justify">Dopo aver impostato i pesi non ci resta altro che dare alla rete l&#8217;input e propagarlo attraverso i neuroni. Si usano anche qui tre cicli for annidati per scorrere tutti i neuroni della rete neurale e per calcolare la somma degli input pesati. Notate che c&#8217;è un if che distingue due casi: se ci troviamo al primo livello nascosto l&#8217;input dovremo prenderlo dai neuroni di input (che altro non sono che gli elementi dell&#8217;array passato come argomento): questo lo facciamo alla linea:</p>
<p align="justify">
<pre class="brush: cpp;">
totInput += layers[i]-&gt;getNeuron(j)-&gt;getWeight(k) * input[k];
</pre>
<p align="justify">
<p align="justify">Come vedete, il k-esimo peso del neurone viene moltiplicato per il k-esimo input, che altro non è che un valore dall&#8217;array.</p>
<p align="justify">Quando non siamo più al primo livello, ma a quelli successivi l&#8217;input andrà preso da neuroni precedenti ed infatti:</p>
<p align="justify">
<pre class="brush: cpp;">
totInput += layers[i]-&gt;getNeuron(j)-&gt;getWeight(k) * layers[i-1]-&gt;getNeuron(k)&gt;getValue();
</pre>
<p align="left">
<p align="justify">Il k-esimo peso del neurone viene moltiplicato per il valore contenuto nel k-esimo neurone del livello precedente (layers[i-1]). La backslash dopo il * sta solamente ad indicare che la linea è spezzata per ragioni di formattazione, ma che il codice va su una sola riga. La variabile totInput conterrà alla fine del ciclo la sommatoria pesata degli input del neurone. Subito dopo il ciclo viene definita una variabile con il valore dell&#8217;ultimo peso del neurone (questo peso non è stato preso in considerazione quando facevamo la sommatoria, se notate, nel ciclo abbiamo passato il parametro false alla funzione getWeightsNum() facendoci così restituire il numero dei pesi meno 1). Questo sarà il bias che alla riga successiva viene sottratto al valore totale del  neurone dopo che quest&#8217;ultimo è stato passato attraverso la funzione sigmoid() cioè la funzione di trasferimento sigmoidale. Dal punto di vista grafico potete immaginare il bias semplicemente come una traslazione sull&#8217;asse y del grafico della funzione e questo comporta che la funzione non sia centrata nel punto per ogni neurone ma che ogni neurone abbia appunto una funzione centrata in un punto differente.</p>
<p align="justify">Il compito della funzione è finito qui, poiché dopo tutti questi cicli i neuroni dell&#8217;ultimo livello, cioè i neuroni di output conterrano il risultato ottenuto dalla rete.</p>
<p align="justify">L&#8217;ultima funzione degna di nota è globalError(): essa calcola l&#8217;errore della rete facendo la differenza tra ogni output ed il rispettivo output desiderato specificato nel training set. Ci servirà in seguito per assegnare il fitness ad i nostri cromosomi.</p>
<p align="justify">Nella prossima parte parleremo delle classi relative alla gestione dei cromosomi e metteremo in pratica quello che abbiamo visto teoricamente nella parte seconda quindi continuate a visitarci!</p>
<p align="justify">Link alle parti precedenti:</p>
<p align="justify"><a title="Reti neurali attraverso algoritmi genetici in C++. Parte I" href="http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-i/" target="_self">Parte I</a></p>
<p align="justify"><a title="Reti neurali attraverso algoritmi genetici in C++. Parte II" href="http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-ii/" target="_self">Parte II</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iii/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Generatore di rumore bianco</title>
		<link>http://mindunpacked.com/2008/generatore-di-rumore-bianco/</link>
		<comments>http://mindunpacked.com/2008/generatore-di-rumore-bianco/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 23:15:06 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[BC107]]></category>
		<category><![CDATA[Generatore]]></category>
		<category><![CDATA[Rumore bianco]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=107</guid>
		<description><![CDATA[Questo è un progetto molto semplice che vi permetterà di produrre il famoso rumore bianco. Non è nulla di speciale, ma questo particolare fruscio, vista la sua peculiarità di presentare un&#8217;ampiezza costante su tutto lo spettro di frequenze, viene usato per molto scopi, soprattutto in elettronica.
Vi presento subito lo schema:




R1: 1 megaohom
C2: 820 pF ceramico


R2: [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Questo è un progetto molto semplice che vi permetterà di produrre il famoso rumore bianco. Non è nulla di speciale, ma questo particolare fruscio, vista la sua peculiarità di presentare un&#8217;ampiezza costante su tutto lo spettro di frequenze, viene usato per molto scopi, soprattutto in elettronica.<span id="more-107"></span></p>
<p>Vi presento subito lo schema:</p>
<p style="text-align: center;"><img class="size-full wp-image-108 aligncenter" title="schema-rumore-bianco" src="http://mindunpacked.com/wp-content/uploads/2008/11/schema-rumore-bianco.gif" alt="" width="486" height="297" /></p>
<table style="height: 124px;" border="0" cellspacing="0" cellpadding="0" width="353" align="center">
<tbody>
<tr>
<td>R1: 1 megaohom</td>
<td>C2: 820 pF ceramico</td>
</tr>
<tr>
<td style="text-align: left;">R2: 3,3 megaohm</td>
<td style="text-align: left;">C3: 680.000 pF poliestere</td>
</tr>
<tr>
<td>R3: 10 kohm</td>
<td>C4: 47.000 pF ceramico</td>
</tr>
<tr>
<td>R4: 100 kohm</td>
<td>C5: 5.000 pF ceramico</td>
</tr>
<tr>
<td>R5: 100 kohm</td>
<td>TR1: NPN tipo BC107</td>
</tr>
<tr>
<td>R6: 680 ohm</td>
<td>TR2: NPN tipo BC107</td>
</tr>
<tr>
<td>C1: 100.000 pF ceramico</td>
<td style="text-align: left;">IC1: integrato uA741</td>
</tr>
</tbody>
</table>
<p style="text-align: justify;"><span style="color: #ffffff;">.</span></p>
<p style="text-align: justify;">Lo schema circuitale è oltremodo semplice ed in base a questa ragione si presta ad essere analizzato da chiunque. Il componente responsabile della generazione del rumore è il transistor TR1 (un BC107) il quale è polarizzato inversamente tramite la resistenza R1; tale resistenza. essendo di valore sufficientemente elevato, fa sì che la corrente dell&#8217;emettitore di tale transistor risulti molto bassa,  ma a sua volta sufficiente a far sì che la tensione emettitore-base di TR1 assuma un valore tale da portarla alla rottura: in tal modo viene pertanto a generarsi un rumore continuo. Tale rumore presenta a questo punto un&#8217;ampiezza (livello) molto bassa che non può essere utilizzata se non dopo un&#8217;opportuna amplificazione. A ciò provvede il transistor TR2, che amplifica il segnale inviandolo a sua volta ad un unteriore stadio di amplificazione, costituito dall&#8217;integrato uA741. Quest&#8217;ultimo viene alimentato con una tensione di 12 v sul piedino 7, mentre viene polarizzato con metà dell&#8217;alimentazione sull&#8217;ingresso.<br />
Se vorrete rendere udibile il fruscio dovrete collegare all&#8217;uscita un amplificatore di bassa frequenza e di conseguenza un altoparlante. Per altri scopi, invece, il segnale che preleverete all&#8217;uscita sarà più che sufficiente.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/generatore-di-rumore-bianco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Algoritmi steganografici</title>
		<link>http://mindunpacked.com/2008/algoritmi-steganografici/</link>
		<comments>http://mindunpacked.com/2008/algoritmi-steganografici/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 20:13:48 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[permutazione]]></category>
		<category><![CDATA[S-Tools]]></category>
		<category><![CDATA[Steganografia]]></category>
		<category><![CDATA[Texto]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=67</guid>
		<description><![CDATA[Nel precedente articolo avevo parlato dell&#8217;algoritmo LSB, che è il capostipite degli algoritmi steganografici basati sulla sostituzione dei bit ridondanti. In questo articolo descriverò abbastanza dettagliatamente uno degli algoritmi steganografici più utilizzati, ovvero quello di Andrew Brown, fra l&#8217;altro implementato in un software chiamato S-Tools.
Prima di arrivare a ciò, vorrei descrivere come la steganografia possa [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm; text-align: justify;">Nel <a href="http://mindunpacked.com/2008/introduzione-alla-steganografia-digitale/" target="_blank">precedente articolo</a> avevo parlato dell&#8217;algoritmo <strong>LSB</strong>, che è il capostipite degli algoritmi steganografici basati sulla sostituzione dei bit ridondanti. In questo articolo descriverò abbastanza dettagliatamente uno degli algoritmi steganografici più utilizzati, ovvero quello di <strong>Andrew Brown</strong>, fra l&#8217;altro implementato in un software chiamato S-Tools.<span id="more-67"></span><br />
Prima di arrivare a ciò, vorrei descrivere come la steganografia possa essere attaccata in modo da vanificarne gli scopi.</p>
<p style="margin-bottom: 0cm; text-align: justify;">In primis va chiarito che colui che tenta di violare una trasmissione di informazioni segreta viene chiamato steganalista, e la sua materia di studio è la steganalisi. Secondo il principio di Kerckhoff, valido egualmente anche in crittografia, la sicurezza della steganografia non fa imputata al fatto che il sistema steganografico sia sconosciuto allo steganalista, ma bensì che la sola chiave per accedere all&#8217;informazione non sia nota.<br />
Gli attacchi si possono raggruppare in due piccoli gruppi, quelli passivi e quelli attivi:</p>
<p style="margin-bottom: 0cm;" align="left"><span style="color: #ff6600;"><strong>Attacchi passivi:</strong></span></p>
<p style="text-align: justify;"><strong>stego-only-attack:</strong> lo stegoanalista intercetta il file steganografato ed è in grado di 	analizzarlo. E&#8217; il più importante tipo di attacco contro un sistema 	steganografico perché è quello che solitamente capita di 	utilizzare.<br />
<strong>stego-attack:</strong> il mittente ha usato lo stesso 	cover ripetutamente per nascondere i dati. Lo steganalista  possiede 	un file steganografato diverso ma originato dallo stesso cover. La 	differenza è che il messaggio celato all&#8217;interno sarà diverso, ma 	il compito di analisi sarà agevolato dal fatto che il file 	contenitore è il medesimo. Per rendere inutile questo tipo di 	attacco, come anche il precedente, basta avere l&#8217;accortezza di 	utilizzare sempre un file contenitore diverso, e soprattutto di 	scarsa notorietà.<br />
<strong>cover-stego-attack:</strong> In questo caso lo 	steganalista intercetta un file steganografato ma è a conoscenza di 	quale file “vergine” è stato utilizzato come cover. Basterà 	fare un confrontro tra i due per identificare i bit modificati, ed 	in caso di assenza di protezioni aggiuntive, risalire 	all&#8217;informazione.<br />
<strong>cover-emb-stego-attack:</strong> Bè, questo è il caso più favorevole, in cui lo stegoanalista possiede tutte le informazioni necessarie per estrapolare l&#8217;informazione. Tuttavia ad successiva sessione i dati potrebbero cambiare, e quindi costringere l&#8217;analista ad un stego-only-attack.</p>
<p><strong><span style="color: #008000;">Attacchi attivi:</span></strong></p>
<p><strong>manipulating the stego data:</strong> L&#8217;analista è in grado di frapporsi tra il mittente ed il destinatario, modificare il file steganografato eliminando l&#8217;informazione occultata e quindi inviare il file modificato al destinatario. Una sorta di attacco man in the middle.<strong><br />
manipulating the cover data:</strong> In questo caso si è in grado di manipolare il cover e intercettare il file steganografato. Si potrà risalire all&#8217;informazione nascosta attraverso passaggi più o meno compessi, magari sempre confrontando i due file cercando di scoprire i bit incriminati.<strong><br />
</strong><br />
<!--adsense--><br />
<span style="color: #999999;"><strong>L&#8217;algoritmo di A. Brown e S-Tools</strong></span></p>
<p style="margin-bottom: 0cm; text-align: justify;">Andrew Brown è l&#8217;artefice di uno degli algoritmi steganografici più utilizzati, che lui stesso ha implementato in un software chiamato S-Tools (scaricabile <a href="ftp://ftp.ntua.gr/pub/crypt/mirrors/idea.sec.dsi.unimi.it/code/s-tools4.zip">qui</a>).</p>
<p style="margin-bottom: 0cm; text-align: justify;">Si tratta di un algoritmo sostitutivo appartenente alla famiglia LSB. E&#8217; in grado di nascondere più messaggi nello stesso file, che in questo caso può essere un&#8217;immagine in formato gif o bitmap oppure un file sonoro con estensione wav. L&#8217;algoritmo procede attraverso tre fasi:</p>
<ul>
<li>
<p style="margin-bottom: 0cm;" align="justify">Compressione dei file da 	nascondere</p>
</li>
<li>
<p style="margin-bottom: 0cm;" align="justify">Cifratura dei dati 	mediante vari algoritmi (<strong>IDEA</strong>, <strong>DES</strong>, <strong>triplo DES</strong> e <strong>MDC</strong>) con password 	scelta dall&#8217;utente</p>
</li>
<li>
<p style="margin-bottom: 0cm;" align="justify">Generazione casuale di 	una serie di numeri che individuano i byte dove inserire il 	messaggio nascosto.</p>
</li>
</ul>
<p style="margin-bottom: 0cm; text-align: justify;">I primi due stadi sono dei preliminari e consentono di pretrattare i dati da nascondere secondo metodi distinti dalla steganografia; essi infatti vengono compressi in modo che occupino meno spazio e quindi criptati per avere un ulteriore grado di sicurezza. Il primo punto consente anche di avere un cover di dimensioni più piccole.</p>
<p style="margin-bottom: 0cm; text-align: justify;">Il terzo passo è il più importante da un punto di vista steganografico. Tale fase si occupa di iniettare il messaggio nascosto nei bit meno significativi di alcuni byte scelti casualmente, o meglio, a seconda della password inserita dall&#8217;utente. Considerando come file di copertura un wav, è noto come quest&#8217;ultimo si ottiene attraverso la simultanea applicazione dei due procedimenti di campionamento e <a href="http://it.wikipedia.org/wiki/Convertitore_analogico-digitale" target="_blank">quantizzazione</a>. Per esempio in Windows la quantizzazione è attuata con 8 o 16 bit, cosicché si può attingere rispettivamente a scale di 256 e <strong>65536</strong> valori. Cambiare il bit meno significativo di alcuni byte che operano la digitalizzazione, soprattutto nel secondo caso, produce modificazioni impercettibili anche alla più sensibile delle orecchie. Si stratta quindi di un processo del tutto analogo a quello adottato per le immagini. La particolarità dell&#8217;algoritmo di Brown sta nel fatto che i byte da modificare vengono scelti casualmente e dipendono sempre dalla password immessa dall&#8217;utente.</p>
<p style="margin-bottom: 0cm; text-align: justify;"><span style="color: #ffffff;">.</span></p>
<p style="margin-bottom: 0cm; text-align: justify;"><strong>Steganografia nei testi : Texto</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Alcuni algoritmi sono in grado di nascondere dei messaggi all&#8217;interno di frasi opportunamente generate, ed è proprio questo il caso di Texto (sorgenti scaricabili <a href="http://www.nic.funet.fi/pub/crypt/steganography/texto.tar.gz">qui</a>), un programma sviluppato da Kevin Maher. Va detto subito che le frasi prodotte, pur avendo un significato grammaticale, assumono un indiscutibile valore semantico, apparendo il più delle volte come periodi demenziali. Ovviamente le frasi generate da Texto sono in inglese, essendo lo stesso autore di lingua anglosassone. Maher ha approntato un dizionario di parole divise in categorie che sono: oggetti, luoghi, verbi, avverbi e aggettivi. Inoltre ha generato delle frase che fanno da template da completare con le parole appena menzionate.<br />
Ogni categoria è costituita da 64 alternative, quindi si possono codificare fino a 6 bit, ed essendo gli spazi vuoti cinque (per ciascun template), il testo segreto per ogni frase può essere costituito da un massimo di 30 bit. Il tutto funziona se il mittente ed il destinatario utilizzano il medesimo dizionario, inoltre è facile intuire come l&#8217;esigua quantità di parole faciliti il compito dello steganalista. Tuttavia la sicurezza può essere aumentata ampliando il dizionario ed il numero di template, o magari cifrando il testo prima di steganografarlo.</p>
<p style="margin-bottom: 0cm;"><strong><br />
</strong></p>
<p><span style="color: #999999;"><strong> <span>Permutazioni pseudo-casuali</span></strong></span></p>
<p style="margin-bottom: 0cm; text-align: justify;">Gli algoritmi di <strong>permutazione pseudo-casuale</strong> appartengono sempre alla famiglia degli LSB e si basano ugualmente sulla modifica dei bit meno significativi. La differenza sta nella scelta dei byte da modificare, che non viene fatta come una sequenza seppure random come nel caso di <strong>S-Tools</strong>, ma con la permutazione di un sottoinsieme di tali byte. Una permutazione di n oggetti è la nuova disposizione degli stessi secondo un nuovo ordine. Il numero totale di permutazioni aumenta in modo esponenziale all&#8217;aumentare del numero di oggetti – byte in questo caso. In particolare le permutazioni di n byte sono n! (n <a href="http://it.wikipedia.org/wiki/Fattoriale" target="_blank">fattoriale</a>), quindi anche una piccola frase da 512 bit può essere permutata in talmente tanti modi che l&#8217;analizzarli tutti richiederebbe – anche ad un computer – un tempo non indifferente. Scegliendo come successione di byte da modificare una permutazione del sottoinsieme prescelto si perde la caratteristica di ordine, cosicché il messaggio occultato viene “sparpagliato” tra i byte del cover. La distribuzione non ordinata dei bit modificati tra i byte disponibili fornisce un ulteriore elemento di sicurezza contro eventuali attacchi.<br />
Questa è una tecnica utilizzata molto anche in crittografia, ma ovviamente le modalità di impiego sono ben diverse.</p>
<h3 style="margin-bottom: 0cm; text-align: justify;"><span style="color: #ffffff;">.</span></h3>
<p style="margin-bottom: 0cm; text-align: justify;"><strong>Conclusione</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Bè, si fa per dire. D&#8217;altronde di cose da esporre sulla steganografia ce ne sarebbero ancora molte, ma diciamo che per il momento è tutto. Per il futuro ho intenzione di illustrarvi come funziona un&#8217;altra interessante applicazione pratica della steganografia, ovvero i file system steganografati. Continuate a seguirci <img src='http://mindunpacked.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/algoritmi-steganografici/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Reti neurali attraverso algoritmi genetici in C++. Parte II</title>
		<link>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-ii/</link>
		<comments>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-ii/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 18:00:53 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Algoritmi genetici]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=88</guid>
		<description><![CDATA[Algoritmi genetici.
Gli algoritmi genetici sono algoritmi particolari che si ispirano all&#8217;evoluzione naturale delle specie descritta da Darwin. Essi sono molto utilizzati nel risolvere problemi nei quali lo spazio di ricerca delle soluzioni non è ben definito e garantiscono sempre un avvicinamento alla soluzione ideale del problema. In un algoritmo genetico ogni individuo (cromosoma) possiede un [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center"><strong>Algoritmi genetici.</strong></p>
<p style="text-align: justify;">Gli algoritmi genetici sono algoritmi particolari che si ispirano all&#8217;evoluzione naturale delle specie descritta da Darwin. Essi sono molto utilizzati nel risolvere problemi nei quali lo spazio di ricerca delle soluzioni non è ben definito e garantiscono sempre un avvicinamento alla soluzione ideale del problema. In un algoritmo genetico ogni individuo (cromosoma) possiede un <strong>DNA</strong> che rappresenta una potenziale soluzione del problema. Una popolazione di un certo numero di individui con DNA casuale viene creata e su di essa agiscono varie operazioni atte a simulare la selezione naturale per scegliere via via quelli che più si avvicinano alla soluzione desiderata. Il DNA di ogni individuo è in genere una soluzione del problema codificata in modo da facilitare le operazioni genetiche che bisogna fare su di essa (crossover, mutazioni genetiche, etc&#8230;, le vedremo fra poco).</p>
<p><span id="more-88"></span></p>
<p style="text-align: justify;">Per fare un esempio, potremmo scegliere di creare un algoritmo genetico che cerchi due numeri interi che diano come somma il numero (intero) passatogli in input. Un esempio di DNA per questo algoritmo potrebbe essere il seguente:</p>
<p style="text-align: left">00010100</p>
<p style="text-align: justify;">Dove le due quartine rappresentano i due numeri da noi cercati codificati in forma binaria. La forma binaria non è l&#8217;unica possibile per codificare il DNA, infatti ognuno potrebbe scegliere di usare un&#8217;altra codifica, ma nel caso appena descritto si rivela abbastanza comoda (anche perchè è di facile decodifica). Ora abbiamo visto come si codifica il DNA, ma come avviene l&#8217;evoluzione? Vediamolo.</p>
<p style="text-align: justify;">All&#8217;inizio viene creata una popolazione di individui con DNA casuale e ogni individuo di questa popolazione viene valutato, cioè gli viene dato un punteggio più o meno alto in base a quanto si è avvicinato alla soluzione che cerchiamo. Qui entra in gioco una delle parti più importanti nell&#8217;algoritmo genetico e cioè la <strong>funzione di fitness</strong>. Il fitness è proprio il punteggio ottenuto da ogni individuo e questa funzione serve a calcolarlo. Nel nostro caso è molto facile creare una funzione di fitness: per assegnare un punteggio basta semplicemente fare la differenza in valore assoluto tra il numero desiderato in output e il numero ottenuto tramite la somma dei due numeri codificati. Supponiamo di volere il numero 12 come output e di avere due cromosomi con il seguente DNA:</p>
<p style="text-align: left">1) 00010010</p>
<p style="text-align: left">2) 01000101</p>
<p style="text-align: justify;">Il primo codifica i numeri 1 e 2 in forma binaria (0001 == 1, 0010 == 2) mentre il secondo i numeri 4 e 5 (0100 == 4, 0101 == 5). Ilcromosoma 1) da come risultato 3 mentre il 2) da come risultato 9. Se calcoliamo il fitness semplicemente facendo la differenza il primo avra&#8217; un fitness di 121= 11, mentre il secondo 129= 3. Chiaramente nel nostro esempio il fitness più basso corrisponde al cromosoma migliore e un fitness pari a 0 corrisponde all&#8217;aver raggiunto la soluzione perfetta. La funzione di fitness in questo caso è molto semplice, ma spesso è un fattore determinante per la buona riuscita di un algoritmo genetico: scegliere una funzione di fitness al posto di un&#8217;altra puo&#8217; cambiare drasticamente i risultati!</p>
<p style="text-align: justify;">Dopo aver calcolato il fitness per tutti gli individui della popolazione, si passa alla riproduzione. La riproduzione avviene emulando la selezione naturale e cioè facendo sopravvivere gli individui più forti (quelli con il fitness migliore) ed eliminando quelli più deboli. Durante la riproduzione avvengono anche i fenomeni del crossover e della mutazione che servono a creare varietà  genetica (altrimenti i cromosomi resterebbero sempre gli stessi) e che vedremo fra un istante.</p>
<p style="text-align: justify;">Gli individui da far riprodurre non posso essere scelti casualmente, perchè altrimenti non si assisterebbe mai ad un miglioramento con il passare delle generazioni (ah, per generazione si intende  ogni ciclo completo di riproduzione), perciò esistono vari metodi di selezione e noi useremo quella che viene chiamata selezione a torneo (tournament selection). Giusto per la cronaca, un altro dei metodi di selezioni molto utlizzati è la “<strong>roulette  wheel selection</strong>” che assegna ad ogni cromosoma una probabilità di essere selezionato direttamente proporzionale al suo fitness. La selezione a torneo consiste nello scegliere casualmente N individui dalla popolazione di partenza e di confrontare il loro fitness: quello con il fitness migliore viene scelto per la riproduzione. La selezione a torneo permette di variare facilmente la pressione selettiva: più è alto il numero N degli individui partecipanti al torneo è più basse saranno le possibilità di riproduzione degli individui con fitness basso (con basso intendo semplicmente peggiore e non minore numericamente, perchè come abbiamo visto, nel nostro caso, un fitness minore equivale ad un punteggio migliore).</p>
<p><!--adsense--></p>
<p style="text-align: justify;">Gli individui con fitness basso, sono comunque tutt&#8217;altro che inutili perchè in seguito alla ricombinazione genetica, possono fornire materiale utile alla ricerca della soluzione (leggete più avanti per averne un esempio). In genere vengono scelti due cromosomi alla volta (e quindi vengono effettuati due &#8220;tornei&#8221;) e da loro nascono due nuovi individui. I figli, se così si possono chiamare, non avranno lo stesso patrimonio genetico dei genitori (altrimenti non assisteremmo mai ad un miglioramento e l&#8217;individuo migliore della prima generazione resterebbe sempre il migliore per tutte le generazioni seguenti) ma avranno un patrimonio che deriva dal loro in seguito ad alcune modifiche. Ad introdurre queste modifiche sono due operatori genetici: il crossover e la mutazione. Chi ha studiato un po&#8217; di biologia dovrebbe conoscere almeno in linea teorica il crossover: esso avviene quando due cromosomi si rompono in un determinato punto e si scambiano una parte di DNA. Supponiamo di avere due cromosomi:</p>
<p style="text-align: left">1) <span style="color: #ff0000;">00100</span> <span style="color: #ff0000;">100</span> ( 2 + 4 = 6 ) fitness = 6</p>
<p style="text-align: left">2) <span style="color: #ff0000;">00011 010</span> ( 1 + 10 = 11 ) fitness = 1</p>
<p style="text-align: left">
<p style="text-align: justify;">e supponiamo di scegliere come punto di rottura quello indicato dalla freccia. Effettuando il crossover nasceranno due figli con i seguenti DNA:</p>
<p style="text-align: left">1a) <span style="color: #ff0000;">00100</span><span style="color: #0000ff;">010 </span> ( 2 + 2 = 4 ) fitness = 8</p>
<p style="text-align: left">2b) <span style="color: #0000ff;">00011</span><span style="color: #ff0000;">100 </span> ( 1 + 12 = 13 )  fitness = 1</p>
<p style="text-align: justify;">che come vedete sono l&#8217;incrocio dei due DNA precedenti. Il crossover è fondamentale perchè puo&#8217; produrre nuovi cromosomi che si avvicinano molto di piu&#8217; alla soluzione: nell&#8217;esempio il cromosoma 2b) dà come risultato 13 che è quasi la soluzione che cercavamo. E&#8217; interessante notare come, in questo caso, un individuo con fitness basso (il cromosoma 1) con fitness 6) abbia contribuito in maniera fondamentale al raggiungimento della soluzione. Generalmente il crossover non avviene sempre, ma si stabilisce una probabilità (il 70% va bene) con cui farlo avvenire. Dopo aver creato i due nuovi individui su di essi agisce un altro operatore genetico, la mutazione, che effettua un cambiamento su un singolo gene del DNA. Se il DNA è  codificato in forma binaria la mutazione non fa altro che trasforamare uno 0 in un 1 o viceversa. Anch&#8217;essa non si verifica in ogni riproduzioni ma ha una probabilità che in genere è molto piu&#8217; bassa rispetto a quella del crossover. Questo procedimento di riproduzione si ripete fino a che la nuova popolazione non ha un numero di individui pari a quella vecchia e poi si ricomincia tutto da capo: si rivaluta il fitness dei nuovi individui (se tutto va bene troveremo qualcuno con un fitness migliore), si effettua una nuova riproduzione, etc&#8230; tutto questo si ripete fino a che non troviamo una soluzione accettabile al nostro problema.</p>
<p style="text-align: justify;">Probabilmente sarete un po&#8217; confusi, e ora vi starete chiedendo cosa c&#8217;entrino gli algoritmi genetici con le reti neurali. Fra un secondo vi sarà tutto più chiaro. Abbiamo detto che la parte fondamentale per ottenere risultati esatti con una rete neurale è trovare una configurazione ottimale dei pesi e sarà proprio per trovare i valori di tutti i pesi della rete che useremo gli algoritmi genetici. Il DNA dei nostri cromosomi rappresenterà i pesi della rete e via via cercheremo di individuare soluzioni migliori facendo riprodurre quei cromosomi il cui DNA fornisce risultati con un errore più basso quando viene eseguito nella rete. In pratica prendiamo un cromosoma e sostituiamo il suo DNA ai pesi della rete e verifichiamo quant&#8217;è l&#8217;errore prodotto: in questo caso la funzione di fitness corrisponde semplicemente all&#8217;errore, ed anche qui cromosomi con fitness più basso (e quindi con errore più basso) saranno migliori. C&#8217;e&#8217; da notare anche che il DNA non verra codificato ma sarà costituito da un semplice vettore di double che contiene tutti i pesi di tutti i neuroni della rete neurale.</p>
<p style="text-align: justify;">La parte sugli algoritmi genetici è terminata e spero che quello che ho scritto sia sufficiente a farvi capire quello che implementeremo. Consiglio ancora una volta a chi non ha ben chiari questi concetti di leggere alcuni dei tuorial sugli algoritmi genetici consigliati in fondo e soprattutto, di provare a realizzare una propria implementazione di un piccolo algoritmo genetico perchè può aiutare molto.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-ii/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Il metilcatinone</title>
		<link>http://mindunpacked.com/2008/il-metilcatinone/</link>
		<comments>http://mindunpacked.com/2008/il-metilcatinone/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 17:55:21 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Chimica]]></category>
		<category><![CDATA[CAT]]></category>
		<category><![CDATA[metcatinone]]></category>
		<category><![CDATA[Metilcatinone]]></category>
		<category><![CDATA[pseudo-efedrina]]></category>
		<category><![CDATA[sintesi]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=46</guid>
		<description><![CDATA[



/td>


Il  Metilcatinone (metcatinone, CAT) è un’ammina simpaticomimetica strutturalmente simile alla metedrina. Presenta una funzione carbonilica sul carbonio adiacente al gruppo aromatico e questo (analogamente al dietilpropione) condiziona il superamento della barriera emato-encefalica, modificandone l’intensità dell’effetto a livello del sistema nervoso centrale. Allo stato di base libera è un liquido oleoso di colore giallastro insolubile [...]]]></description>
			<content:encoded><![CDATA[<table style="text-align: left; height: 282px;" border="0" cellspacing="0" cellpadding="15" width="627">
<tbody>
<tr>
<td>
<p><div id="attachment_85" class="wp-caption alignnone" style="width: 210px"><img class="size-medium wp-image-85" title="Metilcatinone - molecola animata" src="http://mindunpacked.com/wp-content/uploads/2008/11/cat1.gif" alt="Metilcatinone - molecola animata" width="200" height="200" /><p class="wp-caption-text">Metilcatinone - molecola animata</p></div></td>
<td>
<blockquote style="margin-left: 0cm; margin-right: -0.08cm;">
<p style="padding-left: 30px; text-align: justify;"><span style="font-size: 13;">Il  <strong>Metilcatinone</strong> (metcatinone, CAT) è un’ammina simpaticomimetica strutturalmente simile alla metedrina. Presenta una funzione carbonilica sul carbonio adiacente al gruppo aromatico e questo (analogamente al dietilpropione) condiziona il superamento della barriera emato-encefalica, modificandone l’intensità dell’effetto a livello del sistema nervoso centrale. Allo stato di base libera è un liquido oleoso di colore giallastro insolubile in H<sub>2</sub>O, e solubile nei comuni solventi apolari. Il suo sale più comune è il cloridrato, allo stato di polvere in fiocchi di colore bianco candido, di sapore amaro, odore leggero gradevole, vagamente somigliante al pistacchio.</span></p>
</blockquote>
</td>
</tr>
</tbody>
</table>
<p style="text-align: left;"><span style="font-size: 13;">Questa sostanza ha degli effetti molto simili alla metanfetamina, ma di intensità minore. Gli effetti comuni sono tachicardia, ipertensione, incapacità di smettere di parlare, pupille dilatate e squilibrio delle funzioni sessuali. In generale gli effetti sono quelli che si manifestano con una qualsiasi anfetamina. Un alto dosaggio somministrato per lunghi periodi può portare a paranoia e psicosi, tuttavia interrompendo l&#8217;assunzione questi sintomi svaniscono abbastanza velocemente.<br />
</span></p>
<p style="text-align: left;"><span id="more-46"></span></p>
<p style="text-align: left;"><span style="font-size: 13;">Come vedremo ora anche il metilcatinone può essere sintetizzato dall&#8217;<strong>efedrina</strong> tramite un processo di ossidazione:</span></p>
<blockquote style="margin-left: 0cm; margin-right: -0.08cm; text-align: left;">
<p style="text-align: center;"><img class="size-full wp-image-47 aligncenter" title="ossidazione/riduzione efedrina" src="http://mindunpacked.com/wp-content/uploads/2008/11/1.gif" alt="" width="500" height="241" /></p>
</blockquote>
<blockquote style="margin-left: 0cm; margin-right: -0.08cm; text-align: left;">
<p style="text-indent: 0.02cm; text-align: justify;"><span style="font-size: 13;">L’<strong>ossidazione</strong> (e la riduzione) processa uno solo dei due stereocentri (quello adiacente al fenile), lasciando l’altro intatto. Le due forme in cui è ottenibile l’efedrina sono la levo-, che costituisce la stragrande maggioranza dell’alcaloide naturale, e la forma destro, detta pseudo-efedrina, realizzabile sinteticamente, e presente in tracce in natura. Queste due forme dell’efedrina ruotano da parti opposte il piano della luce polarizzata, pur presentando, però, la medesima configurazione sul C2 (il carbonio propilico recante la funzione azotata), ed è così che per ossidazione sia della levo-efedrina sia della pseudo si otterrà uno solo dei due <a href="http://it.wikibooks.org/wiki/Chimica_organica/Stereochimica#Propriet.C3.A0_degli_enantiomeri" target="_blank">enantiomeri</a> possibili, esattamente il destro, ed il prodotto che si otterrà è otticamente attivo. Lo stesso avviene per la riduzione. In entrambe le reazioni sia si utilizzi come precursore l’efedrina naturale o la pseudo sintetica si otterranno prodotti otticamente attivi, il metilcatinone e la metedrina entrambi nella forma D, per l’ossidazione e la riduzione, rispettivamente.<br />
La reazione di ossidazione, pur non essendo stereoselettiva, ci consente di ottenere un prodotto otticamente puro. Questo in teoria. In pratica, però, è facile che il metilcatinone ottenuto presenti un certo grado di racemizzazione, se non si opera con attenzione. Infatti, si tratta di un chetone enolizzabile, come si può vedere dalle strutture seguenti:</span></p>
<p style="text-indent: 0.02cm;"><img class="size-full wp-image-48 alignleft" title="forma chetonica &lt;--&gt; forma enoica" src="http://mindunpacked.com/wp-content/uploads/2008/11/2.gif" alt="" width="493" height="126" /></p>
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify">
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify">
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify">
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify">
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify"><span style="font-size: 13;">Per migrazione dell’idrogeno in C2 sull’ossigeno carbonilico il doppio legame si sposta, così il C2 modifica il proprio stato di ibridazione da sp 3 a sp 2, da tetraedrico a trigonale, e conseguentemente cambia anche gli angoli di legame da 109,5° a 120°, il che comporta che quando si ripristina l’assetto originale l’attacco dell’idrogeno può avvenire da ambo le parti del piano delineato dal C2 trigonale e dei suoi tre orbitali sigma, con formazione di due antipodi ottici, ed il prodotto che si otterrà perderà l’attività ottica originale, cioè racemizza. Come per la metedrina, <strong>la forma D del metilcatinone è attiva come stimolante del sistema nervoso centrale</strong>, la forma L lo è molto meno. Dunque, con la racemizzazione si perderà una notevole parte dell’effetto farmacologico del composto.<br />
Fatta questa parte teorica passiamo ora a qualcosa di più pratico, ovvero al procedimento solitamente utilizzato per ossidare l&#8217;efedrina (in questo caso pseudo-efedrina di tipo D).</span></p>
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify">
<p style="text-indent: 0.02cm; margin-bottom: 0cm;" align="justify">
<p><!--adsense--></p>
<blockquote>
<p style="text-align: left;"><strong>MATERIALE NECESSARIO:</strong></p>
<p style="text-align: left;">- Colino o colapasta con buchi relativamente piccoli<br />
- Ghiaccio tritato<br />
- Pastiglie di pseudoefedrina (100 da 30 mg o equivalente).<br />
- <a href="http://it.wikipedia.org/wiki/Permanganato_di_potassio" target="_blank">Permanganato di potassio</a> (KMnO4).<br />
- Acqua distillata<br />
- Congelatore<br />
- Bilancia più precisa possibile (almeno 0,1 g) o in alternativa una pipetta o altro metodo per misurare i millilitri<br />
- Isopropanolo (dal 70% al 100%)<br />
- Filtri da caffè, o filtri analoghi a trama fine.<br />
- Vari barattoli di vetro e un piatto in Pyrex<br />
- Acido cloridrico (HCl)<br />
- Etanolo, per velocizzare il processo di cristallizzazione (facoltativo)<br />
- Acetone per lavare i cristalli (facoltativo)</p>
<p style="text-align: left;"><strong><br />
ESTRAZIONE DELLA PSEUDO-EFEDRINA HCl:</strong></p>
<p style="text-align: justify;">Porre le pastiglie nel colapasta insieme a un volume all’incirca uguale di ghiaccio tritato, e mescolare sopra un lavandino fino a quando tutto il ghiaccio non si sarà sciolto. A questo punto risciacquare le pastiglie con acqua distillata e riporle in un barattolo di vetro.<br />
Versare sulle pastiglie appena lavate 150 ml di acqua distillata e riscaldare il tutto a microonde, a bassa potenza, fino a farlo diventare caldo (senza bollirlo). Mescolare finchè le compresse non si disgregano e lasciare depositare gli eccipienti sul fondo, in modo da lasciare la pseudoefedrina in soluzione.<br />
Versare la soluzione attraverso un filtro da caffè, facendo in modo di versare solo la parte acquosa e non il deposito solido sul fondo, che andrebbe a ostruire il filtro, e raccoglierlo in un altro barattolo.<br />
Fatto ciò raccogliere il materiale solido nel filtro, rimetterlo nel primo barattolo, aggiungere altri 150 ml di acqua, riscaldare e ripetere la filtrazione. Ripetere di nuovo quest’ ultima parte.</p>
<p style="text-align: left;"><strong>PREPARAZIONE DELLA SOLUZIONE DI KMnO4:</strong></p>
<p style="text-align: justify;">Se l’estrazione della pseudoefedrina è stata perfetta, ce ne sono ora in soluzione esattamente 3 grammi. Considerando che il rapporto molare pseudoefedrina/KMnO4 deve essere 2.5 moli contro 1, e che 3 grammi di pseudoefedrina equivalgono a 18.15 mMoli, per la reazione sono necessarie 7.26 mMoli di KMnO4, equivalenti a 1.148 grammi. Se non si dispone di una bilancia di precisione è possibile determinare questa quantità realizzando una soluzione satura di KMnO4, aspettando in modo che il corpo di fondo si depositi del tutto, e misurare 15.45 ml (se non è possibile essere così precisi arrotondare per eccesso).</p>
<p style="text-align: left;"><strong>PREPARAZIONE DELLA REAZIONE:</strong></p>
<p style="text-align: justify;">Diluire i 15 ml (o 1.148 grammi) in 250 ml di acqua distillata e porre il tutto nel congelatore, insieme alla soluzione di pseudoefedrina. Lasciar raffreddare per almeno 4 ore. Per avere un indicazione della temperatura si può controllare quando il ghiaccio inizia a formarsi e lasciare quindi che si sciolga in modo da essere sicuri che la temperatura sia 0°C.</p>
<p style="text-align: left;"><strong>REAZIONE:</strong></p>
<p style="text-align: justify;">Unire le due soluzioni, mescolare e riporre nel congelatore per 8-12 ore. Al termine di questo periodo, il contenuto del vaso avrà cambiato colore, diventando da rosso a limpido, con un deposito marroncino sul fondo. Aggiungere 100 ml di isopropanolo e mescolare.<br />
Se il colore rosso rimane c’è un eccesso di KMnO4 e la sintesi è fallita, oppure non è stato concesso abbastanza tempo alla reazione per avvenire. In ogni caso non lasciar reagire per più di 12 ore. Lasciar riposare la mistura per circa 2 ore, finchè non raggiunge la temperatura ambiente.<br />
Filtrare attraverso 2 filtri da caffè impilati uno sull’altro, in modo da catturare le particelle di manganese che sono precipitate. Dopo una prima filtrazione, raffredare nuovamente e gentilmente la mistura e rifiltrare. Potrebbero essere necessarie più filtrazione successive.</p>
<p style="text-align: left;"><strong>PURIFICAZIONE:</strong></p>
<p style="text-align: left;">Misurare il ph della soluzione con una cartina tornasole, dovrebbe risultare basico, se risulta acido non sarà necessario aggiungere altro acido.<br />
Se la soluzione risulta basica è necessario aggiungere acido cloridrico in modo da ottenere il sale cloridrato del metacatinone, una forma che, a differenza della forma freebase, non si decompone facilmente in efedrina.<br />
Aggiungere una goccia di HCl alla volta, mescolando e controllando il ph finchè non risulta leggermente acido (compreso tra 5 e 6.5).</p>
<p style="text-align: left;">Porre il tutto nel piatto di Pyrex, metterlo su un fornello e riscaldarlo gentilmente da sotto, asciugandolo leggermente con un asciugacapelli. Quando i primi cristalli iniziano a formarsi aggiungere l’etanolo, che velocizza il processo di cristallizzazione. Evitare di riscaldare troppo i cristalli o si scioglieranno e tutta la sintesi sarà fallita.</p>
</blockquote>
<blockquote>
<p style="text-align: left;">A questo punto è possibile (ma non indispensabile) lavare i cristalli con acetone per renderli più puri e trasparenti, anche se questo potrebbe ridurre drasticamente il prodotto in termini di peso.</p>
</blockquote>
<blockquote style="margin-left: 0cm;">
<p style="text-align: left;"><span style="color: #333333;"><strong>Questo è quanto, ovviamente il metilcatinone è una sostanza controllata in italia, ed è presente in tabella 1, quindi ogni processo di sintesi del suddetto composto è da ritenersi assolutamente illegale e non va in nessun caso messo in pratica.</strong></span></p>
</blockquote>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/il-metilcatinone/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Reti neurali attraverso algoritmi genetici in C++. Parte I</title>
		<link>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-i/</link>
		<comments>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-i/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 23:05:10 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Algoritmi genetici]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Intelligenza artificiale]]></category>
		<category><![CDATA[Reti neurali]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=37</guid>
		<description><![CDATA[PREFAZIONE
Le reti neurali sono un argomento molto ostico per molti all&#8217;inizio.
Anche io per riuscire ad implementare la mia prima rete neurale funzionante ci ho impiegato molto tempo ma ho soprattutto dovuto provare e riprovare più volte passando per diversi fallimenti. Mi sono accorto che molti dei tutorial che si trovano in giro tralasciano alcuni aspetti [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center"><strong>PREFAZIONE</strong></p>
<p style="text-align: justify;">Le <strong>reti neurali</strong> sono un argomento molto ostico per molti all&#8217;inizio.<br />
Anche io per riuscire ad implementare la mia prima <strong>rete neurale</strong> funzionante ci ho impiegato molto tempo ma ho soprattutto dovuto provare e riprovare più volte passando per diversi fallimenti. Mi sono accorto che molti dei tutorial che si trovano in giro tralasciano alcuni aspetti o li spiegano in maniera poco chiara, e tra l&#8217;altro i tutorial in lingua italiana sull&#8217;argomento sono anche pochi.<br />
Con questo tutorial cercherò di creare un documento che comprenda almeno le basi per rendere chiunque lo legga, ed abbia alcuni prerequisiti elencati in seguito, capace di implementare una rete neurale.<br />
<span id="more-37"></span></p>
<p style="text-align: center"><strong>Nota sul codice.</strong></p>
<p style="text-align: justify;">Prima di iniziare va scritta una piccola nota sul codice: il codice che troverete nell&#8217;archivio che vi sarà dato alla fine di questa guida, non è esattamente lo stesso che trovate scritto in questa serie di tutorial. Questo perchè ho fatto in seguito delle modifiche (minori) che comunque non cambiano in sostanza la struttura del codice, ma aggiungono solo qualche funzionalità alla rete neurale. Non dovrebbe essere difficile seguirlo lo stesso.</p>
<p style="text-align: center"><strong>PREREQUISITI</strong></p>
<p style="text-align: justify;">Ho cercato di rendere questa guida comprensibile alla maggior parte delle persone (anche a quelle che sull&#8217;argomento reti neurali sono poco informate) ma restano sempre degli argomenti che vengono dati per scontati per la comprensione del testo.<br />
Sono:</p>
<ul>
<li>Buona conoscenza del C++ e della programmazione OO</li>
<li>Basi matematiche</li>
<li>Conoscenza degli <strong>algoritmi genetici</strong></li>
</ul>
<p style="text-align: justify;">L&#8217;ultimo punto non è strettamente necessario, visto che tenterò di spiegare almeno quello che serve sapere sugli algoritmi genetici per implementare la nostra rete, ma se avete gia&#8217; una conoscenza dell&#8217;argomento di certo avrete meno difficoltà a comprendere alcuni concetti. Alla fine del tutorial sono consigliati una serie di link utili la cui lettura e caldamente consigliata.</p>
<p style="text-align: center"><strong>PARTE GENERALE</strong></p>
<p style="text-align: center"><strong>Introduzione.</strong></p>
<p style="text-align: justify;">Questa Parte generale del tutorial contiene alcuni elementi di base come il funzionamento di un <strong>neurone</strong> biologico, la struttura di un neurone artificiale (cioè quello che noi implementeremo) e la struttura di una rete neurale artificiale. Ho inserito anche una piccola parte sugli <strong>algoritmi genetici</strong> che non tratta esaustivamente l&#8217;argomento ma dovrebbe dare almeno l&#8217;infarinatura necessaria a comprendere per quale motivo li useremo e come li useremo. Comunque, come ho scritto sopra, consiglio lo stesso la lettura di altri tutorial più approfonditi se avete difficoltà a comprendere quello che dico sugli algoritmi genetici. Avrei tralasciato volentieri questa parte, perchè penso che molti di voi già la conoscano se hanno letto almeno qualche altro documento sull&#8217;argomento reti neurali. Purtroppo mi tocca scriverla lo stesso visto che è un requisito fondamentale per la<br />
comprensione delle parti successive e questo tutorial mira ad essere il più chiaro possibile anche per chi è agli inizi. Comunque, se conoscete già questi argomenti potete tranquillamente saltare tutta la Parte generale del tutorial e passare a leggere direttamente il resto.<br />
<!--adsense--></p>
<p style="text-align: center;"><strong>Come funziona un neurone biologico.</strong></p>
<p style="text-align: justify;">I neuroni sono le cellule che costituiscono la nostra mente e che trasmettono i segnali nervosi (sia tra di loro che verso le altre parti del corpo). Ogni uomo posside circa 100 miliardi di neuroni (o almeno dovrebbe) variamente collegati tra di loro attraverso una struttura che prende il nome di sinapsi.<br />
Ogni neurone possiede un lungo prolungamento chiamato assone e diverse ramificazioni più piccole che prendono il nome di dendriti. Attraverso i dendriti (che sono collegati agli assoni di altri neuroni) la cellula riceve i segnali che gli vengono inviati, mentre attraverso l&#8217;assone viene mandato un nuovo segnale.<br />
Se non avete ben chiaro cio&#8217; che abbiamo detto fino ad ora, l&#8217;immagine seguente dovrebbe chiarvi le idee:</p>
<div class="wp-caption alignnone" style="width: 410px"><img title="Schema di un neurone biologico" src="http://mindunpacked.com/images/neuron.bmp" alt="Schema di un neurone biologico" width="400" height="216" /><p class="wp-caption-text">Schema di un neurone biologico</p></div>
<p style="text-align: justify;">(Nella figura sono presenti parti del neurone che non ho nominato, come per esempio la guaina mielinica, perche&#8217; non sono utili al nostro scopo).<br />
In generale, quando un neurone riceve un segnale, se esso supera una certa soglia (detta soglia di attivazione), propaga quel segnale attraverso il suo assone agli altri neuroni, altrimenti resta inattivo.</p>
<p style="text-align: center"><strong>Come funziona una rete neurale.</strong></p>
<p style="text-align: justify;">Un <strong>neurone artificiale</strong> tenta di emulare il comportamento di quello biologico, anche se in maniera molto semplificata.<br />
Ogni neurone (d&#8217;ora in poi con il termine neurone mi riferirò esclusivamente a quelli artificiali) ha una serie di collegamenti pesati in ingresso e  fornisce un output in base agli input ricevuti dai collegamenti. Per collegamento pesato si intende un collegamento al quale è anche associato un peso,<br />
che rappresenta, in poche parole, la forza del collegamento e quindi quanto esso potrà influenzare l&#8217;output del neurone.<br />
Il peso non è altro che un numero, generalmente compreso tra 0 e 1 (o tra 1e 1).<br />
L&#8217;informazione trasportata dal collegamento (parliamo sempre di un numero) viene moltiplicata per il peso e quindi varia al variare del peso (resta invariata quando esso è uguale a 1, diventa nulla quando è 0 e diventa l&#8217;opposto quando è 1).<br />
Come vedremo, sarà proprio il valore dei pesi a determinare l&#8217;esattezza dei risultati della nostra rete ed è appunto variando i pesi tramite speciali algoritmi che si tenta di raggiungere una configurazione ottimale. Ricordo che i pesi subito dopo l&#8217;inizializzazione della rete hanno valori casuali.<br />
Il neurone, dopo aver ricevuto gli input pesati da tutti i collegamenti in ingresso li somma. La sommatoria degli input pesati viene poi passata ad una funzione chiamata funzione di attivazione che fa propagare il segnale ai neuroni successivi.<br />
Spesso, e questo comportamento differisce da quello del neurone biologico, non viene stabilita una soglia minima di attivazione al di sotto della quale il neurone non invia nessuno stimolo, ma questo dipende dalla funzione di attivazione scelta e lo vedremo più tardi.<br />
Le reti che andremo ad implementare in questo tutorial sono definite <strong>reti feedforward</strong> perchè l&#8217;impulso si propaga sempre nella stessa direzione; esistono molti altri tipi di reti e ognuna è più adatta ad alcuni compiti particolari, ma non ne parleremo in questo tutorial.<br />
Una rete neurale è formata appunto da un certo numero di neuroni, chiaramente molto minore di quello del nostro cervello: in genere alcune decine di neuroni sono in grado di compiere compiti anche piuttosto complessi.<br />
I neuroni di una rete sono organizzati in diversi livelli, o strati, e ognuno di essi ha un compito preciso. Il primo strato è quello di input: contiene i neuroni che ricevono l&#8217;input e non hanno collegamenti pesati; non essendo infatti i dati che ricevono provenienti da nessun altro neurone essi immagazzinano semplicemente il dato così come è e lo trasmettono al livello successivo.<br />
Lo strato di input può essere collegato direttamente a quello di output oppure tra di essi si può trovare un certo numero di strati nascosti (<strong>hidden layers</strong>): per gli scopi di questo tutorial useremo una rete con un solo strato nascosto il quale è più che sufficiente per svolgere i compiti che ci interessano.</p>
<p style="text-align: justify;">Abbiamo visto la struttura di una rete neurale, ma come fa essa ad apprendere? Va detto che esistono due tipi di <strong>apprendimento</strong>: quello <strong>supervisionato</strong> (che tratteremo in questo tutorial) e quello non supervisionato.</p>
<p style="text-align: justify;">Usando il primo tipo di apprendimento la rete necessita di una prima fase di addestramento durante la quale le vengono forniti alcuni esempi comprendenti sia l&#8217;input che l&#8217;output desiderato. La rete viene eseguita con questi input di cui si conosce già in precedenza il risultato e tramite alcuni algoritmi vengono modificati i pesi della rete per fornire risultati sempre più accurati. Quando la fase di allenamento è finita (cioè si e&#8217; raggiunta una soglia minima di errore stabilita in precedenza) la rete è in grando non solo di dare un risultato esatto se gli forniamo gli stessi dati che gli<br />
abbiamo fornito nel <strong>training set</strong> (gli esempi) ma anche con dati in input che non ha mai visto. Questo avviene perchè la rete non associa un singolo input all&#8217;output corrispondente ma scopre la relazione che li lega. Potremmo per esempio allenare una <strong>rete neurale</strong> ad imparare a fare la somma di due numeri fornendo un training set del genere:</p>
<table style="text-align: center" border="0">
<tbody>
<tr>
<td>Primo input</td>
<td>Secondo input</td>
<td>Output desiderato</td>
</tr>
<tr>
<td>0.1</td>
<td>0.2</td>
<td>0.3</td>
</tr>
<tr>
<td>0.1</td>
<td>0.3</td>
<td>0.4</td>
</tr>
<tr>
<td>0.1</td>
<td>0.4</td>
<td>0.5</td>
</tr>
<tr>
<td>0.1</td>
<td>0.5</td>
<td>0.6</td>
</tr>
<tr>
<td>0.1</td>
<td>0.6</td>
<td>0.7</td>
</tr>
<tr>
<td>0.1</td>
<td>0.7</td>
<td>0.8</td>
</tr>
<tr>
<td>etc&#8230;</td>
<td>etc&#8230;</td>
<td>etc..</td>
</tr>
</tbody>
</table>
<p><!--adsense--></p>
<p style="text-align: justify;">Un training set deve essere il più omogeneo possibile, e deve descrivere una grande varietà di esempi. Un training set in cui il primo input è sempre 0.1 non è per niente buono per ottenere dei risultati soddisfacenti. Più è vasto il training set, inoltre, più sarà alta la <strong>capacità di generalizzazione</strong> della rete, cioè di dare risultati corretti anche quando i dati in input sono per lei sconosciuti, cioè non facevano parte del training set.<br />
Modificando in maniera corretta i pesi della rete essa riconosce la relazione tra gli input e l&#8217;output (e cioè, nel nostro caso, che l&#8217;output deve essere la somma degli input) e dà un risultato corretto. Ricordatevi comunque che l&#8217;applicazione delle reti neurali avviene in campi in cui è più importante la flessibilità e la capacità di generalizzazione della stessa, piuttosto che ottenere risultati precisissimi: quello che voglio dire è che una rete neurale è molto più utile per la sua flessibilità che per la sua precisione, e che per fare la somma di dui numeri è molto meglio usare una calcolatrice. Una rete<br />
addestrata a tale scopo, infatti, dà in genere, risultati approssimati come :<br />
0.5 + 0.5 = 0.99<br />
0.1 + 0.9 = 1.02<br />
o simili.<br />
Chiusa questa piccola parentesi torniamo ai tipi di apprendimento. Il secondo tipo di apprendimento (quello non supervisionato) serve a creare reti<br />
neurali che classificano i dati che gli forniamo in input in diverse categorie (senza fornigli nessun output desiderato, da qui il nome) in base ai loro elementi in comune, ma non verra&#8217; trattato in questo tutorial.<br />
Come avrete capito, la parte più importante per l&#8217;apprendimento della rete neurale è la modifica dei pesi fra le connessioni dei neuroni ed è proprio qui che agiscono gli <strong>algoritmi di apprendimento</strong>. Esistono diversi algoritmi: uno dei piu&#8217; famosi è quello di retro propagazione dell&#8217;errore (error back propagation) che mi limiterò a citare solamente visto che noi faremo uso di algoritmi genetici per fare evolvere la nostra rete.</p>
<p>La prima parte del tutorial finisce qui. A presto.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://analytics.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://analytics.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->
