<?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>Neptalium</title>
	<atom:link href="http://www.neptalium.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.neptalium.com/blog</link>
	<description>Programación; Inteligencia Artificial, Computer Graphics... y demás hierbas del campo en 10 minutos</description>
	<lastBuildDate>Sat, 03 Dec 2011 01:58:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Funciones de Hash</title>
		<link>http://www.neptalium.com/blog/2011/02/funciones-de-hash/</link>
		<comments>http://www.neptalium.com/blog/2011/02/funciones-de-hash/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 19:28:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Matemáticas]]></category>
		<category><![CDATA[Función de Hash]]></category>
		<category><![CDATA[Funciones de Hash]]></category>
		<category><![CDATA[Hash]]></category>
		<category><![CDATA[Hashing]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=551</guid>
		<description><![CDATA[Una función de hash es aquella que convierte una serie de datos en otra serie de datos más corta (generalmente en una simple variable entera de 32 o 64 bits). Esto es especialmente útil para poder identificar/representar una secuencia de datos de una forma mucho más rápida y eficiente. Pero hay que tener en cuenta [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Una función de hash es aquella que convierte una serie de datos en otra serie de datos más corta (generalmente en una simple variable entera de 32 o 64 bits).<br />
Esto es especialmente útil para poder identificar/representar una secuencia de datos de una forma mucho más rápida y eficiente. Pero hay que tener en cuenta que existen infinitas secuencias de datos que dan como resultado el mismo código de hash por lo que no es un proceso reversible, es decir, es prácticamente imposible obtener la secuencia de datos con la que fue calculado el hash a partir del propio hash.</p>
<p><img src="http://www.neptalium.com/blog/wp-content/uploads/2011/02/hash_1.gif" alt="" title="Cálculo de Hash" width="510" height="200" class="aligncenter size-full wp-image-603" /></p>
<p style="text-align: justify;">Por ejemplo, es muy útil para codificar cadenas de caracteres y de esta forma poder realizar búsquedas mucho más rápidamente, o como simple sistema de indexación de datos.<br />
También se utilizan en criptografía y como sistemas de comprobación de integridad de los datos, algunos ejemplos de este tipo de funciones de hash son la <b>CRC</b>, <b>MD5</b>, <b>MD4</b>, <b>Tiger</b>, <b>RMD</b>, <b>SHA</b>, etc.</p>
<p><img src="http://www.neptalium.com/blog/wp-content/uploads/2011/02/hash_2.gif" alt="" title="Ejemplo de Función de Hash" width="460" height="321" class="aligncenter size-full wp-image-611" /></p>
<p style="text-align: justify;">El principal problema surge cuando es imprescindible que cada secuencia de datos tenga un identificador hash único, si dos o más secuencias tienen el mismo hash se produce una <b>colisión de hash</b>. En este ejemplo las cadenas <em>&#8220;Jirafa&#8221;</em> y <em>&#8220;Tigre&#8221;</em> tienen el mismo hash, 02.</p>
<p><img src="http://www.neptalium.com/blog/wp-content/uploads/2011/02/hash_3.gif" alt="" title="Colisión de Hash" width="276" height="230" class="aligncenter size-full wp-image-605" /></p>
<p style="text-align: justify;">Existen infinitas formas de hacer una función de hash y puedes crear la tuya propia fácilmente, el problema es conseguir que la función genere una buena distribución de los hashes y, a ser posible, que produzca las menores colisiones posibles incluso con secuencias de datos muy cortas y similares. Por eso es recomendable utilizar alguna de las muchas funciones de hash que se utilizan desde hace tiempo y están muy probadas.<br />
Aqui dejo un video del MIT de introducción a las técnicas de hashing:</p>
<p style="text-align: center;"><iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/JZHBa-rLrBA" frameborder="0" allowfullscreen></iframe></p>
<p>Sin mas historias vamos con algunas de las funciones de hashing de 32 bits más básicas y utilizadas:</p>
<p>Esta surgió de una idea presentada al comité del IEEE POSIX P1003.2 por Glenn Fowler y Phong Vo en 1991, luego Landon Curt Noll la mejoró.<br />
Funciona muy bien, es rápida y produce pocas colisiones. Realiza una buena dispersión de los hashes y va muy bien para hacer hashing en cadenas casi idénticas como URLs, URIs, IPs, nombres de archivo, etc.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashFNV<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">const</span> UI32 fnv_prime <span style="color: #000080;">=</span> <span style="color: #208080;">0x811C9DC5</span><span style="color: #008080;">;</span><br />
&nbsp; UI32 &nbsp; &nbsp; &nbsp; hash &nbsp; &nbsp; &nbsp;<span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000040;">*</span><span style="color: #000080;">=</span> fnv_prime<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; hash <span style="color: #000040;">^</span><span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es del profesor Daniel J. Bernstein, es una de las más eficientes:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashDJB<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">5381</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> hash<span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es de Donald E. Knuth, está en el volumen III de su libro <em>&#8220;The Art of Computer Programming&#8221;</em>:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashDEK<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> len<span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">^</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">27</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">^</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span> <br />
&nbsp; <br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta está basada en el trabajo de Peter J. Weinberger de los laboratorios AT&#038;T.<br />
En el libro <em>&#8220;Compilers (Principles, Techniques and Tools)&#8221;</em> se recomienda su uso:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashPJW<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">const</span> UI32 bits_in_ui32 &nbsp; <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>UI32<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>UI32<span style="color: #008000;">&#41;</span> <span style="color: #000040;">*</span> <span style="color: #0000dd;">8</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">const</span> UI32 three_quarters <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>UI32<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>bits_in_ui32 &nbsp;<span style="color: #000040;">*</span> <span style="color: #0000dd;">3</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">/</span> <span style="color: #0000dd;">4</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">const</span> UI32 one_eighth &nbsp; &nbsp; <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>UI32<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>bits_in_ui32 <span style="color: #000040;">/</span> <span style="color: #0000dd;">8</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">const</span> UI32 high_bits &nbsp; &nbsp; &nbsp;<span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>UI32<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #208080;">0xFFFFFFFF</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #008000;">&#40;</span>bits_in_ui32 <span style="color: #000040;">-</span> one_eighth<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; UI32 &nbsp; &nbsp; &nbsp; test &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> <br />
&nbsp; UI32 &nbsp; &nbsp; &nbsp; hash &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> one_eighth<span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>test <span style="color: #000080;">=</span> hash <span style="color: #000040;">&amp;</span> high_bits<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>hash <span style="color: #000040;">^</span> <span style="color: #008000;">&#40;</span>test <span style="color: #000080;">&gt;&gt;</span> three_quarters<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span>~high_bits<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es muy similar a la PJW, pero está optimizada para procesadores de 32 bits.<br />
Se utiliza en la mayoría de los sistemas UNIX:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashELF<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 x &nbsp; &nbsp;<span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">4</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>x <span style="color: #000080;">=</span> hash <span style="color: #000040;">&amp;</span> <span style="color: #208080;">0xF0000000</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; hash <span style="color: #000040;">^</span><span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>x <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">24</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; hash <span style="color: #000040;">&amp;</span><span style="color: #000080;">=</span> ~x<span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es del libro <em>&#8220;The C Programming Language&#8221;</em> de Dennis Ritchie y Brian Kernighan:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashBKDR<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span> <br />
<span style="color: #008000;">&#123;</span> <br />
&nbsp; <span style="color: #0000ff;">const</span> UI32 seed <span style="color: #000080;">=</span> <span style="color: #0000dd;">131</span><span style="color: #008080;">;</span> <br />
&nbsp; UI32 &nbsp; &nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000040;">*</span> seed<span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es una función de hash del libro <em>&#8220;Algorithms in C&#8221;</em> de Robert Sedgwicks:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashRS<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 a &nbsp; &nbsp;<span style="color: #000080;">=</span> <span style="color: #0000dd;">63689</span><span style="color: #008080;">;</span><br />
&nbsp; UI32 b &nbsp; &nbsp;<span style="color: #000080;">=</span> <span style="color: #0000dd;">378551</span><span style="color: #008080;">;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> hash <span style="color: #000040;">*</span> a <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; a &nbsp; &nbsp;<span style="color: #000080;">=</span> a <span style="color: #000040;">*</span> b<span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es una función de hash de Justin Sobel:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashJS<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">1315423911</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000040;">^</span><span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta realiza una buena distribución de los hash en muchos tipos diferentes de secuencias de datos:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashSDBM<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">6</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">16</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">-</span> hash<span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta realiza un simple hashing rotativo/aditivo:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashBP<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">7</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">^</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Y por último, ésta hecha a partir de las anteriores, también es una mezcla de hash rotativo y aditivo:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UI32 HashAP<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>data, UI32 len<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; UI32 hash <span style="color: #000080;">=</span> <span style="color: #208080;">0xAAAAAAAA</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>UI32 i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> len<span style="color: #008080;">;</span> data<span style="color: #000040;">++</span>, i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; hash <span style="color: #000040;">^</span><span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>i <span style="color: #000040;">&amp;</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> &nbsp;<span style="color: #0000dd;">7</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">^</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span> <span style="color: #000040;">*</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">3</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#40;</span>~<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000dd;">11</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span> <span style="color: #000040;">^</span> <span style="color: #008000;">&#40;</span>hash <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>hash<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2011/02/funciones-de-hash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Little Endian y Big Endian</title>
		<link>http://www.neptalium.com/blog/2010/08/little-endian-y-big-endian/</link>
		<comments>http://www.neptalium.com/blog/2010/08/little-endian-y-big-endian/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 19:33:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Programación de Redes]]></category>
		<category><![CDATA[Big Endian]]></category>
		<category><![CDATA[Endian]]></category>
		<category><![CDATA[Endianness]]></category>
		<category><![CDATA[htonl]]></category>
		<category><![CDATA[htons]]></category>
		<category><![CDATA[Little Endian]]></category>
		<category><![CDATA[ntohl]]></category>
		<category><![CDATA[ntohs]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=472</guid>
		<description><![CDATA[¿De qué va esto del endian? No, no se trata de indios pequeñitos&#8230; El endianness de un procesador indica, básicamente, el orden de almacenamiento de los bytes de las variables de más de un byte en la memoria. Los dos tipos de endian principales son el Little-Endian y el Big-Endian. En little-endian los bytes se [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">¿De qué va esto del endian? No, no se trata de indios pequeñitos&#8230;<br />
El <strong><em>endianness</em></strong> de un procesador indica, básicamente, el orden de almacenamiento de los bytes de las variables de más de un byte en la memoria.<br />
Los dos tipos de endian principales son el <strong><em>Little-Endian</em></strong> y el <strong><em>Big-Endian</em>.</strong><br />
En little-endian los bytes se almacenan en orden inverso al natural, es decir, primero el byte menos significativo (LSB) y de último el más significativo (MSB).<br />
Por ejemplo el número de 32 bits <strong>0&#215;10203040</strong> se almacena así en memoria (cada recuadro representa un byte):</p>
<p><img class="aligncenter size-full wp-image-477" title="Little-Endian, 32 bits" src="http://www.neptalium.com/blog/wp-content/uploads/2010/08/little_endian_32.gif" alt="" width="226" height="41" /></p>
<p>Y el número de 16 bits <strong>0&#215;1020</strong> así:</p>
<p><img class="aligncenter size-full wp-image-476" title="Little-Endian, 16 bits" src="http://www.neptalium.com/blog/wp-content/uploads/2010/08/little_endian_16.gif" alt="" width="112" height="41" /></p>
<p>En big-endian se sigue el orden normal, primero el byte más significativo (MSB) y de último el menos significativo (LSB):</p>
<p><img class="aligncenter size-full wp-image-475" title="Big-Endian, 32 bits" src="http://www.neptalium.com/blog/wp-content/uploads/2010/08/big_endian_32.gif" alt="" width="226" height="41" /></p>
<p><img class="aligncenter size-full wp-image-474" title="Big-Endian, 16 bits" src="http://www.neptalium.com/blog/wp-content/uploads/2010/08/big_endian_16.gif" alt="" width="112" height="41" /></p>
<p style="text-align: justify;">En la plataforma PC (procesadores <strong>Intel</strong> y <strong>AMD</strong>) se utiliza little-endian así como en los <strong>Z80</strong> y <strong>VAX</strong>.<br />
Los procesadores <strong>Motorola 68000</strong>, los <strong>PowerPC (de Motorola)</strong> y los <strong>SPARK (de Sun)</strong> son big-endian.<br />
Luego hay procesadores que son configurables y pueden operar en los dos formatos; <strong>MIPS</strong>, <strong>ARM</strong> y los <strong>SPARC</strong> y <strong>PowerPC</strong> modernos, por ejemplo.</p>
<p style="text-align: justify;">Como regla general si un programa va a ser compilado y ejecutado en diversas plataformas hay que tener en cuenta el endian y programarlo de forma que se detecte el endian del procesador y se actúe en consecuencia en cada caso, de lo contrario te vas a encontrar con una larga serie de preciosos bugs muy difíciles de rastrear y que te pueden dar largas horas de &#8220;diversión&#8221;.<br />
Hay dos casos principales en donde se debe tener muy en cuenta el endian; el primero es cuando el programa graba/lee archivos y el segundo cuando establece conexiones de red.<br />
El problema en el primer caso es evidente, un ejemplo; con el programa ejecutándose en un PC grabas una serie de estructuras de datos en un archivo, si luego ejecutas el mismo programa en un procesador 68000 y cargas el archivo que previamente habías grabado desde un PC, los datos de las estructuras del archivo se cargarán invertidos ya que el endian de ambas plataformas no es el mismo (se grabaron los datos en little-endian y los lees como big-endian).<br />
Con la programación de red el problema es más simple: todas las transferencias de datos se realizan en big-endian independientemente de la plataforma que las ejecute, éste es el motivo por el cual al formato big-endian también se le conoce como <strong><em>&#8220;Network Byte Order&#8221;</em></strong>.  Por eso las librerías de sockets incluyen funciones de conversión de endian:</p>
<ul style="text-align: justify;">
<li><strong>htonl()</strong>: <em>Host to network byte order (long, 32 bits)</em>. Convierte una variable de 32 bits del endian del procesador a formato big-endian.</li>
<li><strong>ntohl()</strong>: <em>Network to host byte order (long, 32 bits)</em>. Convierte una variable de 32 bits de big-endian al endian del procesador.</li>
<li><strong>htons()</strong>: <em>Host to network byte order (short, 16 bits)</em>. Convierte una variable de 16 bits del endian del procesador a formato big-endian.</li>
<li><strong>ntohs()</strong>: <em>Network to host byte order (short, 16 bits)</em>. Convierte una variable de 16 bits de big-endian al endian del procesador.</li>
</ul>
<p style="text-align: justify;">Volviendo al problema de la grabación de archivos, tienes dos alternativas para evitar este tipo de problemas:</p>
<ul style="text-align: justify;">
<li>La primera forma es incluir una firma al inicio del archivo que servirá no sólo para identificar el tipo de archivo sino también para saber si fue grabado en una plataforma de distinto endian, y si es así ya sabes que tendrás que leerlo invirtiendo los datos, si por ejemplo usas como firma dos bytes al inicio del archivo como <strong>0xAAFF</strong> (un entero de 16 bits) y en otra plataforma al leer el short de la firma se carga como <strong>0xFFAA</strong> significa que el programa tendrá que convertir el endian del archivo, si la hubiera leído como <strong>0xAAFF</strong> entonces significa que el endian del procesador que grabó el archivo y el endian del procesador que lo ha leído son el mismo y no es necesaria ninguna conversión.</li>
<li>La segunda es grabar siempre los archivos en un endian determinado (a ser posible en el endian de la plataforma que se vaya a utilizar con más frecuencia), de esta forma, si por ejemplo has decidido que el archivo sea de formato big-endian lo único que tendrás que hacer es grabarlo y leerlo como big-endian siempre, independientemente de la plataforma. Fácil, no?</li>
</ul>
<p style="text-align: justify;">¿Y cómo detectas el endian de un procesador? Pues muy fácil, comprobando cómo almacena las variables de más de un byte en memoria:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">enum</span> Endian <span style="color: #008000;">&#123;</span> LITTLE_ENDIAN, BIG_ENDIAN <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span> <br />
<br />
Endian ComprobarEndian<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">&amp;</span>i<span style="color: #008000;">&#41;</span> <span style="color: #000080;">==</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> LITTLE_ENDIAN <span style="color: #008080;">:</span> BIG_ENDIAN<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p style="text-align: justify;">Con un puntero char comprobamos el contenido del primer byte en memoria de los cuatro que forman la variable entera <strong><em>i</em></strong> de 32 bits, si el procesador es little-endian el valor 1 estará almacenado en el primer byte de la secuencia en memoria <strong>[0x01, 0x00, 0x00, 0x00]</strong> y por lo tanto la comparación será verdadera y se devolverá <strong><em>LITTLE_ENDIAN</em></strong>, si el procesador es big-endian el 1 estará en el cuarto byte en la memoria <strong>[0x00, 0x00, 0x00, 0x01]</strong> y la comparación será falsa devolviendo por lo tanto <strong><em>BIG_ENDIAN</em></strong>.</p>
<p style="text-align: justify;">Para terminar solo queda por ver cómo cambiar el endian de una variable (de little-endian a big-endian y viceversa), esta función cambia variables de 16 bits (short):</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">short</span> CambiarEndian<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">short</span> valor<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">&amp;</span>valor<span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">char</span> tmp <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> tmp<span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>valor<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Y ésta cambia el endian de variables de 32 bits:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> CambiarEndian<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> valor<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">&amp;</span>valor<span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">char</span> tmp <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> tmp<span style="color: #008080;">;</span><br />
&nbsp; tmp <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> tmp<span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>valor<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2010/08/little-endian-y-big-endian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evaluar expresiones matemáticas</title>
		<link>http://www.neptalium.com/blog/2010/07/evaluar-expresiones-matematicas/</link>
		<comments>http://www.neptalium.com/blog/2010/07/evaluar-expresiones-matematicas/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 17:04:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Inteligencia Artificial]]></category>
		<category><![CDATA[Matemáticas]]></category>
		<category><![CDATA[Árboles Binarios]]></category>
		<category><![CDATA[Evaluar Expresiones Matemáticas]]></category>
		<category><![CDATA[Notación Infija]]></category>
		<category><![CDATA[Notación Polaca Inversa]]></category>
		<category><![CDATA[Notación Postfija]]></category>
		<category><![CDATA[Notación Prefija]]></category>
		<category><![CDATA[Parsing]]></category>
		<category><![CDATA[Reverse Polish Notation]]></category>
		<category><![CDATA[RPN]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=456</guid>
		<description><![CDATA[Existen tres notaciones básicas para representar expresiones matemáticas; infija, prefija y postfija. La infija es la más conocida porque es la que más se utiliza, por ejemplo: (1+2)*(3-4). En forma prefija se representaría como *+12-34, y en forma postfija sería 12+34-*. La forma infija resulta muy sencilla para los humanos, estamos acostumbrados a ella y es [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Existen tres notaciones básicas para representar expresiones matemáticas; <strong>infija</strong>, <strong>prefija</strong> y <strong>postfija</strong>.<br />
La infija es la más conocida porque es la que más se utiliza, por ejemplo: <strong>(1+2)*(3-4)</strong>.<br />
En forma prefija se representaría como <strong>*+12-34</strong>, y en forma postfija sería <strong>12+34-*</strong>.</p>
<p style="text-align: justify;">La forma infija resulta muy sencilla para los humanos, estamos acostumbrados a ella y es muy simple. Sin embargo requiere del uso de paréntesis para establecer el orden correcto de las operaciones a realizar, y esto supone un engorro a la hora de programar un evaluador de expresiones.  El &#8220;truco&#8221; consiste en convertir la expresión de infja a postfija o prefija, de esta forma nos deshacemos de los paréntesis ya que las notaciones prefija y postfija no los necesitan.</p>
<p style="text-align: justify;">Una vez convertida la expresión a notación postfija o prefija es muy fácil crear un árbol binario para calcular el resultado de la expresión.</p>
<p style="text-align: justify;">Los más observadores ya se habrán dado cuenta de que la notación postfija es también conocida como <strong>RPN</strong> (<strong><em>&#8220;Reverse Polish Notation&#8221;</em></strong>, notación polaca inversa). Fué inventada por el filósofo y matemático polaco Lukasiewicz precisamente como una notación alternativa para evitar los paréntesis en la expresiones. Más de uno habrá usado esta notación en las calculadoras RPN, especialmente de HP, ¿verdad?</p>
<p style="text-align: justify;">Vamos a ver con un ejemplo muy simple como, usando simplemente un stack,  se puede convertir cualquier expresión infija (por compleja que sea) a notación postfija. Explicaré solamente la conversión de infija a postfija. La conversión a prefija es igual de sencilla pero lo dejo como ejercicio de pasatiempo para el que le apetezca.</p>
<p>Se va cogiendo cada elemento de la expresión (de izquierda a derecha) y se siguen estos pasos:</p>
<ol>
<li>Si el elemento es un número o variable se copia directamente a la salida.</li>
<li>Si es un paréntesis izquierdo se mete en el stack.</li>
<li>Si es un paréntesis derecho, se van sacando uno a uno todos los elementos del tope del stack (y copiándolos en la salida) hasta encontrar un paréntesis izquierdo en el stack. Finalmente ambos paréntesis se descartan.</li>
<li>Si es un operador y en el tope del stack no hay un operador o hay un operador de menor precedencia entonces se añade el nuevo operador al stack.</li>
<li>Si es un operador y en el tope del stack hay un operador de mayor o igual precedencia entonces se saca el operador del stack y se copia en la salida, y se repite la comparación del operador con el nuevo tope del stack.</li>
<li>Cuando ya no quedan más elementos en la expresión se van sacando uno a uno todos los elementos del stack y se copian en la salida.</li>
</ol>
<p><strong> </strong>Usaré el ejemplo inicial en notación infija: <strong>(1+2)*(3-4)</strong>.</p>
<ul>
<li style="text-align: left;"><strong>(</strong> Se mete en el stack.  <br /><strong>STACK[ ( ]  SALIDA[ ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>1</strong> Se copia en la salida. <br /><strong>STACK[ ( ]  SALIDA[ 1 ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>+</strong> Operador, en el tope del stack no hay otro operador, se mete en el stack. <br /><strong>STACK[ +( ]  SALIDA[ 1 ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>2</strong> Se copia en la salida. <br /><strong>STACK[ +( ]  SALIDA[ 12 ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>) </strong> Se sacan del stack y se copian en la salida todos los elementos hasta encontrar un paréntesis izquierdo.  <br /><strong>STACK[  ]  SALIDA[ 12+ ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>*</strong> Operador, en el tope del stack no hay otro operador, se mete en el stack.  <br /><strong>STACK[ * ]  SALIDA[ 12+ ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>( </strong>Se mete en el stack.  <br /><strong>STACK[ (* ]  SALIDA[ 12+ ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>3</strong> Se copia en la salida. <br /><strong>STACK[ (* ]  SALIDA[ 12+3 ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>-</strong> Operador, en el tope del stack no hay otro operador, se mete en el stack.  <br /><strong>STACK[ -(* ]  SALIDA[ 12+3 ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>4</strong> Se copia en la salida.  <br /><strong>STACK[ -(* ]  SALIDA[ 12+34 ]</strong></li>
<p></p>
<li style="text-align: left;"><strong>)</strong> Se sacan del stack y se copian en la salida todos los elementos hasta encontrar un paréntesis izquierdo.  <br /><strong>STACK[ * ]  SALIDA[ 12+34- ]</strong></li>
<p></p>
<li style="text-align: left;">Ya no quedan más elementos en la expresión, se sacan todos del stack y se copian en la salida.  <br /><strong>STACK[  ]  SALIDA[ 12+34-* ]</strong></li>
<p>
</ul>
<p>El resultado final en notación postfija es <strong>12+34-*</strong></p>
<p>Ahora resulta muy sencillo evaluar la expresión utilizando de nuevo un simple stack.<br />
Vamos cogiendo cada elemento de la expresión en notación postfija (de izquierda a derecha); </p>
<ul>
<li>Si el elemento es un operando (número, variable o constante) se mete en el stack.</li>
<li>Si el elemento es un operador (+, -, *, /, sin, sqrt&#8230;) se saca del stack tantos elementos como parámetros necesite el operador, se realiza la operación y el resultado se mete en el stack.</li>
<li>El proceso se repite hasta que no queden más elementos en la expresión. Al final del proceso habrá en el stack un sólo elemento que corresponde con el resultado final de la evaluación de la expresión.</li>
</ul>
<p>Veamos como evaluar la expresión <strong>12+34-*</strong></p>
<ul>
<li><strong>1</strong> Es un operando, se mete en el stack.<br /> <strong>STACK[ 1 ]</strong>
<li><strong>2</strong> Es un operando, se mete en el stack.<br /><strong>STACK[ 21 ]</strong>
<li><strong>+</strong> Es un operador, como + es un operador binario (necesita dos elementos) se sacan del stack y se realiza la operación (1 + 2) y el resultado se mete en el stack.<br /><strong>STACK[ 3 ]</strong>
<li><strong>3</strong> Es un operando, se mete en el stack.<br /><strong>STACK[ 33 ]</strong>
<li><strong>4</strong> Es un operando, se mete en el stack.<br /><strong>STACK[ 433 ]</strong>
<li><strong>-</strong> Es un operador binario, se sacan dos elementos del stack y se realiza la operación (3 &#8211; 4) y el resultado se mete en el stack.<br /><strong>STACK[ (-1)3 ]</strong>
<li><strong>*</strong> Es un operador binario, se sacan dos elementos del stack y se realiza la operación (3 * (-1)) y el resultado se mete en el stack.<br /><strong>STACK[ (-3) ]</strong>
<li> <strong>Resultado final: -3</strong>
</ul>
<p>También se puede utilizar un árbol binario para evaluar las expresiones. Para crearlos usamos un stack y vamos cogiendo cada elemento de la expresión en notación postfija (de izquierda a derecha);</p>
<ul>
<li>Si el elemento es un número o variable se crea un nodo con él y se mete en el stack.</li>
<li>Si el elemento es un operador binario se crea un nodo con dicho operador, se extraen del stack dos nodos y se le añaden como hijos, finalmente el nuevo nodo se añade al stack.</li>
<li>Si el elemento es un operador unuario se crea un nodo con dicho operador, se extrae del stack un nodo y se le añade como hijo, finalmente el nuevo nodo se añade al stack.</li>
<li>El proceso se repite hasta que no queden más elementos en la expresión.</li>
</ul>
<p><img class="aligncenter size-full wp-image-460" title="" src="http://www.neptalium.com/blog/wp-content/uploads/2010/07/arbol_binario.jpg" alt="" width="266" height="249" /></p>
<p>Para terminar, simplemente recorriendo recursivamente el árbol en inorden podemos calcular el resultado final de la expresión o incluso reconstruirla en su notación infija:</p>
<ol>
<li>Imprimimos paréntesis izquierdo.</li>
<li>Visitamos subárbol izquierdo (*).</li>
<li>Imprimimos la raíz.</li>
<li>Visitamos subárbol derecho (*).</li>
<li>Imprimimos paréntesis derecho.</li>
</ol>
<p>(*): El proceso se repite recursivamente en los pasos 2 y 4.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2010/07/evaluar-expresiones-matematicas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interpolando que es gerundio</title>
		<link>http://www.neptalium.com/blog/2010/06/interpolando-que-es-gerundio/</link>
		<comments>http://www.neptalium.com/blog/2010/06/interpolando-que-es-gerundio/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 18:43:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Computer Graphics]]></category>
		<category><![CDATA[Física]]></category>
		<category><![CDATA[Matemáticas]]></category>
		<category><![CDATA[Función de Interpolación]]></category>
		<category><![CDATA[Funciones de Interpolación]]></category>
		<category><![CDATA[Interpolación Cuadrática]]></category>
		<category><![CDATA[Interpolación Lineal]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=442</guid>
		<description><![CDATA[Hay pocas cosas tan útiles en programación como la interpolación, de hecho son tantos los casos en los que resulta útil (o incluso esencial) que ni me voy a molestar en mencionarlos. Directamente dejo aqui un par de ejemplos, el primero es una función de interpolación lineal: 1234float InterpLineal&#40;float tiempo, float inicio, float fin&#41; &#123; [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Hay pocas cosas tan útiles en programación como la interpolación, de hecho son tantos los casos en los que resulta útil (o incluso esencial) que ni me voy a molestar en mencionarlos.<br />
Directamente dejo aqui un par de ejemplos, el primero es una función de interpolación lineal:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">float</span> InterpLineal<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span> tiempo, <span style="color: #0000ff;">float</span> inicio, <span style="color: #0000ff;">float</span> fin<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color:#800080;">1.0f</span> <span style="color: #000040;">-</span> tiempo<span style="color: #008000;">&#41;</span> <span style="color: #000040;">*</span> inicio <span style="color: #000040;">+</span> tiempo <span style="color: #000040;">*</span> fin<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Esta es una función de interpolación cuadrática (&#8220;Easy In&#8221;):</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">float</span> InterpCuadIn<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span> tiempo, <span style="color: #0000ff;">float</span> inicio, <span style="color: #0000ff;">float</span> fin<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>InterpLineal<span style="color: #008000;">&#40;</span>tiempo <span style="color: #000040;">*</span> tiempo, incio, fin<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Y por último una interpolación cuadrática (&#8220;Easy In-Out&#8221;):</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">float</span> InterpCuadInOut<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span> tiempo, <span style="color: #0000ff;">float</span> inicio, <span style="color: #0000ff;">float</span> fin<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">float</span> medio <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>inicio <span style="color: #000040;">+</span> fin<span style="color: #008000;">&#41;</span> <span style="color: #000040;">*</span> <span style="color:#800080;">0.5f</span><span style="color: #008080;">;</span><br />
&nbsp; tiempo <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color:#800080;">2.0f</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>tiempo <span style="color: #000080;">&lt;=</span> <span style="color:#800080;">1.0f</span><span style="color: #008000;">&#41;</span><br />
&nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>InterpLineal<span style="color: #008000;">&#40;</span>tiempo <span style="color: #000040;">*</span> tiempo, inicio, medio<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; tiempo <span style="color: #000040;">-</span><span style="color: #000080;">=</span> <span style="color:#800080;">1.0f</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>InterpLineal<span style="color: #008000;">&#40;</span>tiempo <span style="color: #000040;">*</span> tiempo, medio, fin<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>En los tres casos se fija el rango a interpolar con los parámetros <em>inicio</em> y <em>fin</em>, y con el parámetro <em>tiempo</em> se indica el punto de interpolación (por supuesto se asume que <em>tiempo</em> tendrá un valor comprendido entre 0.0 y 1.0).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2010/06/interpolando-que-es-gerundio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transformaciones inversas, inversión de matrices</title>
		<link>http://www.neptalium.com/blog/2009/08/transformaciones-inversas-inversion-de-matrices/</link>
		<comments>http://www.neptalium.com/blog/2009/08/transformaciones-inversas-inversion-de-matrices/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 16:43:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Computer Graphics]]></category>
		<category><![CDATA[Matemáticas]]></category>
		<category><![CDATA[Inversión de Matrices]]></category>
		<category><![CDATA[Transformación Inversa]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=365</guid>
		<description><![CDATA[En programación 3D en tiempo real es imprescindible optimizar todo lo posible, y la inversión de matrices homogéneas es uno de los casos complejos (aparentemente) en donde se puede conseguir una excelente optimización siguiendo las reglas del álgebra matricial y conociendo cómo ha sido generada la matriz a invertir (conociendo su estructura). Nota: En este [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">En programación 3D en tiempo real es imprescindible optimizar todo lo posible, y la inversión de matrices homogéneas es uno de los casos complejos (aparentemente) en donde se puede conseguir una excelente optimización siguiendo las reglas del álgebra matricial y conociendo cómo ha sido generada la matriz a invertir (conociendo su estructura).<br />
<br /><em><b>Nota: En este post usaré el formato fila (pre-multiplicación) para representar las matrices y la formulación.</b></em><br />
<br />Vamos a ver primero la inversión aislada de los tres casos básicos, matriz de rotación, escala y traslación:<br />
<br />Si la matriz de rotación <b>R</b> es ortogonal (si sus tres ejes son perpendiculares entre si), entonces su inversa es simplemente su traspuesta:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=R%3D%5Cbegin%7Bbmatrix%7DRXx%26RXy%26RXz%260%5C%5CRYx%26RYy%26RYz%260%5C%5CRZx%26RZy%26RZz%260%5C%5C0%260%260%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="R=\begin{bmatrix}RXx&#038;RXy&#038;RXz&#038;0\\RYx&#038;RYy&#038;RYz&#038;0\\RZx&#038;RZy&#038;RZz&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="R=\begin{bmatrix}RXx&#038;RXy&#038;RXz&#038;0\\RYx&#038;RYy&#038;RYz&#038;0\\RZx&#038;RZy&#038;RZz&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" /><br />
<br /><img src="http://l.wordpress.com/latex.php?latex=R%5E%7B-1%7D%3DR%5E%7BT%7D%3D%5Cbegin%7Bbmatrix%7DRXx%26RYx%26RZx%260%5C%5CRXy%26RYy%26RZy%260%5C%5CRXz%26RYz%26RZz%260%5C%5C0%260%260%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="R^{-1}=R^{T}=\begin{bmatrix}RXx&#038;RYx&#038;RZx&#038;0\\RXy&#038;RYy&#038;RZy&#038;0\\RXz&#038;RYz&#038;RZz&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="R^{-1}=R^{T}=\begin{bmatrix}RXx&#038;RYx&#038;RZx&#038;0\\RXy&#038;RYy&#038;RZy&#038;0\\RXz&#038;RYz&#038;RZz&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" /><br />
<br />La inversa de una matriz de escala <b>S</b> es muy sencilla:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=S%3D%5Cbegin%7Bbmatrix%7DSx%260%260%260%5C%5C0%26Sy%260%260%5C%5C0%260%26Sz%260%5C%5C0%260%260%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="S=\begin{bmatrix}Sx&#038;0&#038;0&#038;0\\0&#038;Sy&#038;0&#038;0\\0&#038;0&#038;Sz&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="S=\begin{bmatrix}Sx&#038;0&#038;0&#038;0\\0&#038;Sy&#038;0&#038;0\\0&#038;0&#038;Sz&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" /><br />
<br /><img src="http://l.wordpress.com/latex.php?latex=S%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7D%5Cfrac%7B1%7D%7BSx%7D%260%260%260%5C%5C0%26%5Cfrac%7B1%7D%7BSy%7D%260%260%5C%5C0%260%26%5Cfrac%7B1%7D%7BSz%7D%260%5C%5C0%260%260%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="S^{-1}=\begin{bmatrix}\frac{1}{Sx}&#038;0&#038;0&#038;0\\0&#038;\frac{1}{Sy}&#038;0&#038;0\\0&#038;0&#038;\frac{1}{Sz}&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="S^{-1}=\begin{bmatrix}\frac{1}{Sx}&#038;0&#038;0&#038;0\\0&#038;\frac{1}{Sy}&#038;0&#038;0\\0&#038;0&#038;\frac{1}{Sz}&#038;0\\0&#038;0&#038;0&#038;1\end{bmatrix}" /><br />
<br />Y la inversa de una matriz de traslación <b>T</b> también es muy simple:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=T%3D%5Cbegin%7Bbmatrix%7D1%260%260%260%5C%5C0%261%260%260%5C%5C0%260%261%260%5C%5CTx%26Ty%26Tz%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="T=\begin{bmatrix}1&#038;0&#038;0&#038;0\\0&#038;1&#038;0&#038;0\\0&#038;0&#038;1&#038;0\\Tx&#038;Ty&#038;Tz&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="T=\begin{bmatrix}1&#038;0&#038;0&#038;0\\0&#038;1&#038;0&#038;0\\0&#038;0&#038;1&#038;0\\Tx&#038;Ty&#038;Tz&#038;1\end{bmatrix}" /><br />
<br /><img src="http://l.wordpress.com/latex.php?latex=T%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7D1%260%260%260%5C%5C0%261%260%260%5C%5C0%260%261%260%5C%5C-Tx%26-Ty%26-Tz%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="T^{-1}=\begin{bmatrix}1&#038;0&#038;0&#038;0\\0&#038;1&#038;0&#038;0\\0&#038;0&#038;1&#038;0\\-Tx&#038;-Ty&#038;-Tz&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="T^{-1}=\begin{bmatrix}1&#038;0&#038;0&#038;0\\0&#038;1&#038;0&#038;0\\0&#038;0&#038;1&#038;0\\-Tx&#038;-Ty&#038;-Tz&#038;1\end{bmatrix}" /><br />
<br />Ahora veamos un caso más práctico, cómo invertir una matriz de transformación <b>RT</b> (es decir, una matriz que primero realiza una rotación y luego una traslación). Es imprescindible saber siempre el orden de las transformaciones contenidas en una matriz para poder optimizar el cálculo de su inversa ya que vamos a optimizar los cálculos por partes y siguiendo una regla muy simple; la inversa del producto de dos matrices es igual al producto invertido de las inversas de dichas matrices: <img src="http://l.wordpress.com/latex.php?latex=%28A%2AB%29%5E%7B-1%7D%3DB%5E%7B-1%7D%2AA%5E%7B-1%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="(A*B)^{-1}=B^{-1}*A^{-1}" style="vertical-align:-20%;" class="tex" alt="(A*B)^{-1}=B^{-1}*A^{-1}" /><br />
<br />Con esta regla tan simple podemos invertir una matriz <b>RT</b> multiplicando la inversa de la traslación por la inversa de la rotación: <img src="http://l.wordpress.com/latex.php?latex=%28R%2AT%29%5E%7B-1%7D%3DT%5E%7B-1%7D%2AR%5E%7B-1%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="(R*T)^{-1}=T^{-1}*R^{-1}" style="vertical-align:-20%;" class="tex" alt="(R*T)^{-1}=T^{-1}*R^{-1}" /> y como ya sabemos que la inversa de una matriz ortogonal es su traspuesta la fórmula final será: <img src="http://l.wordpress.com/latex.php?latex=%28R%2AT%29%5E%7B-1%7D%3DT%5E%7B-1%7D%2AR%5E%7BT%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="(R*T)^{-1}=T^{-1}*R^{T}" style="vertical-align:-20%;" class="tex" alt="(R*T)^{-1}=T^{-1}*R^{T}" /><br />
<br />Con lápiz y papel calculamos la estructura final de la matriz inversa de una transformación <b>RT</b>:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Clarge%28R%2AT%29%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7DRXx%26RYx%26RZx%260%5C%5CRXy%26RYy%26RZy%260%5C%5CRXz%26RYz%26RZz%260%5C%5C-%28RXx%2ATx%2BRXy%2ATy%2BRXz%2ATz%29%26-%28RYx%2ATx%2BRYy%2ATy%2BRYz%2ATz%29%26-%28RZx%2ATx%2BRZy%2ATy%2BRZz%2ATz%29%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\large(R*T)^{-1}=\begin{bmatrix}RXx&#038;RYx&#038;RZx&#038;0\\RXy&#038;RYy&#038;RZy&#038;0\\RXz&#038;RYz&#038;RZz&#038;0\\-(RXx*Tx+RXy*Ty+RXz*Tz)&#038;-(RYx*Tx+RYy*Ty+RYz*Tz)&#038;-(RZx*Tx+RZy*Ty+RZz*Tz)&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\large(R*T)^{-1}=\begin{bmatrix}RXx&#038;RYx&#038;RZx&#038;0\\RXy&#038;RYy&#038;RZy&#038;0\\RXz&#038;RYz&#038;RZz&#038;0\\-(RXx*Tx+RXy*Ty+RXz*Tz)&#038;-(RYx*Tx+RYy*Ty+RYz*Tz)&#038;-(RZx*Tx+RZy*Ty+RZz*Tz)&#038;1\end{bmatrix}" /><br />
<br />Para invertir una matriz <b>TR</b> es incluso más simple: <img src="http://l.wordpress.com/latex.php?latex=%28T%2AR%29%5E%7B-1%7D%3DR%5E%7BT%7D%2AT%5E%7B-1%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="(T*R)^{-1}=R^{T}*T^{-1}" style="vertical-align:-20%;" class="tex" alt="(T*R)^{-1}=R^{T}*T^{-1}" /><br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%28T%2AR%29%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7DRXx%26RYx%26RZx%260%5C%5CRXy%26RYy%26RZy%260%5C%5CRXz%26RYz%26RZz%260%5C%5C-Tx%26-Ty%26-Tz%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="(T*R)^{-1}=\begin{bmatrix}RXx&#038;RYx&#038;RZx&#038;0\\RXy&#038;RYy&#038;RZy&#038;0\\RXz&#038;RYz&#038;RZz&#038;0\\-Tx&#038;-Ty&#038;-Tz&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="(T*R)^{-1}=\begin{bmatrix}RXx&#038;RYx&#038;RZx&#038;0\\RXy&#038;RYy&#038;RZy&#038;0\\RXz&#038;RYz&#038;RZz&#038;0\\-Tx&#038;-Ty&#038;-Tz&#038;1\end{bmatrix}" /><br />
<br />Ahora veremos cómo invertir matrices que incluyen transformaciones de escala isométrica (que significa que se ha aplicado la misma escala a los tres ejes), empecemos por la clásica transformación <b>SRT</b> (donde primero se escala, luego se rota y finalmente se traslada). Como siempre su inversa será: <img src="http://l.wordpress.com/latex.php?latex=%28S%2AR%2AT%29%5E%7B-1%7D%3DT%5E%7B-1%7D%2AR%5E%7BT%7D%2AS%5E%7B-1%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="(S*R*T)^{-1}=T^{-1}*R^{T}*S^{-1}" style="vertical-align:-20%;" class="tex" alt="(S*R*T)^{-1}=T^{-1}*R^{T}*S^{-1}" /><br />
<br />Volvemos a coger el lápiz y calculamos:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Clarge%28S%2AR%2AT%29%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7D%5Cfrac%7BRXx%7D%7BS%7D%26%5Cfrac%7BRYx%7D%7BS%7D%26%5Cfrac%7BRZx%7D%7BS%7D%260%5C%5C%5Cfrac%7BRXy%7D%7BS%7D%26%5Cfrac%7BRYy%7D%7BS%7D%26%5Cfrac%7BRZy%7D%7BS%7D%260%5C%5C%5Cfrac%7BRXz%7D%7BS%7D%26%5Cfrac%7BRYz%7D%7BS%7D%26%5Cfrac%7BRZz%7D%7BS%7D%260%5C%5C-%5Cfrac%7BRXx%2ATx%2BRXy%2ATy%2BRXz%2ATz%7D%7BS%7D%26-%5Cfrac%7BRYx%2ATx%2BRYy%2ATy%2BRYz%2ATz%7D%7BS%7D%26-%5Cfrac%7BRZx%2ATx%2BRZy%2ATy%2BRZz%2ATz%7D%7BS%7D%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\large(S*R*T)^{-1}=\begin{bmatrix}\frac{RXx}{S}&#038;\frac{RYx}{S}&#038;\frac{RZx}{S}&#038;0\\\frac{RXy}{S}&#038;\frac{RYy}{S}&#038;\frac{RZy}{S}&#038;0\\\frac{RXz}{S}&#038;\frac{RYz}{S}&#038;\frac{RZz}{S}&#038;0\\-\frac{RXx*Tx+RXy*Ty+RXz*Tz}{S}&#038;-\frac{RYx*Tx+RYy*Ty+RYz*Tz}{S}&#038;-\frac{RZx*Tx+RZy*Ty+RZz*Tz}{S}&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\large(S*R*T)^{-1}=\begin{bmatrix}\frac{RXx}{S}&#038;\frac{RYx}{S}&#038;\frac{RZx}{S}&#038;0\\\frac{RXy}{S}&#038;\frac{RYy}{S}&#038;\frac{RZy}{S}&#038;0\\\frac{RXz}{S}&#038;\frac{RYz}{S}&#038;\frac{RZz}{S}&#038;0\\-\frac{RXx*Tx+RXy*Ty+RXz*Tz}{S}&#038;-\frac{RYx*Tx+RYy*Ty+RYz*Tz}{S}&#038;-\frac{RZx*Tx+RZy*Ty+RZz*Tz}{S}&#038;1\end{bmatrix}" /><br />
<br />La misma inversa <B>SRT</b> pero de una matriz con escalado anisométrico (escalado no idéntico en los tres ejes) sería:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Clarge%28S%2AR%2AT%29%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7D%5Cfrac%7BRXx%7D%7BSx%7D%26%5Cfrac%7BRYx%7D%7BSy%7D%26%5Cfrac%7BRZx%7D%7BSz%7D%260%5C%5C%5Cfrac%7BRXy%7D%7BSx%7D%26%5Cfrac%7BRYy%7D%7BSy%7D%26%5Cfrac%7BRZy%7D%7BSz%7D%260%5C%5C%5Cfrac%7BRXz%7D%7BSx%7D%26%5Cfrac%7BRYz%7D%7BSy%7D%26%5Cfrac%7BRZz%7D%7BSz%7D%260%5C%5C-%5Cfrac%7BRXx%2ATx%2BRXy%2ATy%2BRXz%2ATz%7D%7BSx%7D%26-%5Cfrac%7BRYx%2ATx%2BRYy%2ATy%2BRYz%2ATz%7D%7BSy%7D%26-%5Cfrac%7BRZx%2ATx%2BRZy%2ATy%2BRZz%2ATz%7D%7BSz%7D%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\large(S*R*T)^{-1}=\begin{bmatrix}\frac{RXx}{Sx}&#038;\frac{RYx}{Sy}&#038;\frac{RZx}{Sz}&#038;0\\\frac{RXy}{Sx}&#038;\frac{RYy}{Sy}&#038;\frac{RZy}{Sz}&#038;0\\\frac{RXz}{Sx}&#038;\frac{RYz}{Sy}&#038;\frac{RZz}{Sz}&#038;0\\-\frac{RXx*Tx+RXy*Ty+RXz*Tz}{Sx}&#038;-\frac{RYx*Tx+RYy*Ty+RYz*Tz}{Sy}&#038;-\frac{RZx*Tx+RZy*Ty+RZz*Tz}{Sz}&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\large(S*R*T)^{-1}=\begin{bmatrix}\frac{RXx}{Sx}&#038;\frac{RYx}{Sy}&#038;\frac{RZx}{Sz}&#038;0\\\frac{RXy}{Sx}&#038;\frac{RYy}{Sy}&#038;\frac{RZy}{Sz}&#038;0\\\frac{RXz}{Sx}&#038;\frac{RYz}{Sy}&#038;\frac{RZz}{Sz}&#038;0\\-\frac{RXx*Tx+RXy*Ty+RXz*Tz}{Sx}&#038;-\frac{RYx*Tx+RYy*Ty+RYz*Tz}{Sy}&#038;-\frac{RZx*Tx+RZy*Ty+RZz*Tz}{Sz}&#038;1\end{bmatrix}" /><br />
<br />Para terminar veremos la inversa de una matriz que represente una transformación <b>RTS</b>. La inversa con escalado isométrico es:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Clarge%28R%2AT%2AS%29%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7D%5Cfrac%7BRXx%7D%7BS%7D%26%5Cfrac%7BRYx%7D%7BS%7D%26%5Cfrac%7BRZx%7D%7BS%7D%260%5C%5C%5Cfrac%7BRXy%7D%7BS%7D%26%5Cfrac%7BRYy%7D%7BS%7D%26%5Cfrac%7BRZy%7D%7BS%7D%260%5C%5C%5Cfrac%7BRXz%7D%7BS%7D%26%5Cfrac%7BRYz%7D%7BS%7D%26%5Cfrac%7BRZz%7D%7BS%7D%260%5C%5C-%28RXx%2ATx%2BRXy%2ATy%2BRXz%2ATz%29%26-%28RYx%2ATx%2BRYy%2ATy%2BRYz%2ATz%29%26-%28RZx%2ATx%2BRZy%2ATy%2BRZz%2ATz%29%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\large(R*T*S)^{-1}=\begin{bmatrix}\frac{RXx}{S}&#038;\frac{RYx}{S}&#038;\frac{RZx}{S}&#038;0\\\frac{RXy}{S}&#038;\frac{RYy}{S}&#038;\frac{RZy}{S}&#038;0\\\frac{RXz}{S}&#038;\frac{RYz}{S}&#038;\frac{RZz}{S}&#038;0\\-(RXx*Tx+RXy*Ty+RXz*Tz)&#038;-(RYx*Tx+RYy*Ty+RYz*Tz)&#038;-(RZx*Tx+RZy*Ty+RZz*Tz)&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\large(R*T*S)^{-1}=\begin{bmatrix}\frac{RXx}{S}&#038;\frac{RYx}{S}&#038;\frac{RZx}{S}&#038;0\\\frac{RXy}{S}&#038;\frac{RYy}{S}&#038;\frac{RZy}{S}&#038;0\\\frac{RXz}{S}&#038;\frac{RYz}{S}&#038;\frac{RZz}{S}&#038;0\\-(RXx*Tx+RXy*Ty+RXz*Tz)&#038;-(RYx*Tx+RYy*Ty+RYz*Tz)&#038;-(RZx*Tx+RZy*Ty+RZz*Tz)&#038;1\end{bmatrix}" /><br />
<br />Y la inversa de una matriz <b>RTS</b> con escala anisométrica es:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Clarge%28R%2AT%2AS%29%5E%7B-1%7D%3D%5Cbegin%7Bbmatrix%7D%5Cfrac%7BRXx%7D%7BSx%7D%26%5Cfrac%7BRYx%7D%7BSy%7D%26%5Cfrac%7BRZx%7D%7BSz%7D%260%5C%5C%5Cfrac%7BRXy%7D%7BSx%7D%26%5Cfrac%7BRYy%7D%7BSy%7D%26%5Cfrac%7BRZy%7D%7BSz%7D%260%5C%5C%5Cfrac%7BRXz%7D%7BSx%7D%26%5Cfrac%7BRYz%7D%7BSy%7D%26%5Cfrac%7BRZz%7D%7BSz%7D%260%5C%5C-%28RXx%2ATx%2BRXy%2ATy%2BRXz%2ATz%29%26-%28RYx%2ATx%2BRYy%2ATy%2BRYz%2ATz%29%26-%28RZx%2ATx%2BRZy%2ATy%2BRZz%2ATz%29%261%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\large(R*T*S)^{-1}=\begin{bmatrix}\frac{RXx}{Sx}&#038;\frac{RYx}{Sy}&#038;\frac{RZx}{Sz}&#038;0\\\frac{RXy}{Sx}&#038;\frac{RYy}{Sy}&#038;\frac{RZy}{Sz}&#038;0\\\frac{RXz}{Sx}&#038;\frac{RYz}{Sy}&#038;\frac{RZz}{Sz}&#038;0\\-(RXx*Tx+RXy*Ty+RXz*Tz)&#038;-(RYx*Tx+RYy*Ty+RYz*Tz)&#038;-(RZx*Tx+RZy*Ty+RZz*Tz)&#038;1\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\large(R*T*S)^{-1}=\begin{bmatrix}\frac{RXx}{Sx}&#038;\frac{RYx}{Sy}&#038;\frac{RZx}{Sz}&#038;0\\\frac{RXy}{Sx}&#038;\frac{RYy}{Sy}&#038;\frac{RZy}{Sz}&#038;0\\\frac{RXz}{Sx}&#038;\frac{RYz}{Sy}&#038;\frac{RZz}{Sz}&#038;0\\-(RXx*Tx+RXy*Ty+RXz*Tz)&#038;-(RYx*Tx+RYy*Ty+RYz*Tz)&#038;-(RZx*Tx+RZy*Ty+RZz*Tz)&#038;1\end{bmatrix}" /><br />
<br />Si teneis dificultades para ver alguna de las matrices pulsad con el botón derecho del ratón sobre ella y elegid <em>Abrir/Ver imagen</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/08/transformaciones-inversas-inversion-de-matrices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Formato interno de las matrices en OpenGL</title>
		<link>http://www.neptalium.com/blog/2009/08/formato-interno-de-las-matrices-en-opengl/</link>
		<comments>http://www.neptalium.com/blog/2009/08/formato-interno-de-las-matrices-en-opengl/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 19:14:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Computer Graphics]]></category>
		<category><![CDATA[Matemáticas]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Matrices]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=317</guid>
		<description><![CDATA[Desde los inicios de OpenGL existe una confusión bastante importante sobre cómo administra internamente las matrices. Unos piensan que las almacena en formato fila y otros piensan que lo hace en formato columna. Pues lo cierto es que ni una cosa ni la otra! OpenGL almacena las matrices en un array unidimensional de 16 elementos [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Desde los inicios de OpenGL existe una confusión bastante importante sobre cómo administra internamente las matrices. Unos piensan que las almacena en formato fila y otros piensan que lo hace en formato columna. Pues lo cierto es que ni una cosa ni la otra!<br />
OpenGL almacena las matrices en un array unidimensional de 16 elementos y es el programador quien decide cómo prefiere interpretarlas.<br />
<br />Quedará más claro con un ejemplo:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">GLfloat m<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">16</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
glGetFloatv<span style="color: #008000;">&#40;</span>GL_MODELVIEW_MATRIX, m<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p style="text-align: justify;">
<br />Con el código anterior leemos la matriz actual MODELVIEW y la almacenamos en el array <em>m</em>.<br />
<br />¿Y cómo están estructurados los elementos de la matriz? Pues muy sencillo, secuencialmente:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=m%20%3D%20%5C%7Bm0%2Cm1%2Cm2%2Cm3%2Cm4%2Cm5%2Cm6%2Cm7%2Cm8%2Cm9%2Cm10%2Cm11%2Cm12%2Cm13%2Cm14%2Cm15%5C%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="m = \{m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15\}" style="vertical-align:-20%;" class="tex" alt="m = \{m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15\}" /><br />
<br />Ahora el programador puede decidir interpretarlo como una matriz de tipo columna:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Cbegin%7Bbmatrix%7Dm0%26m4%26m8%26m12%5C%5Cm1%26m5%26m9%26m13%5C%5Cm2%26m6%26m10%26m14%5C%5Cm3%26m7%26m11%26m15%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\begin{bmatrix}m0&#038;m4&#038;m8&#038;m12\\m1&#038;m5&#038;m9&#038;m13\\m2&#038;m6&#038;m10&#038;m14\\m3&#038;m7&#038;m11&#038;m15\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\begin{bmatrix}m0&#038;m4&#038;m8&#038;m12\\m1&#038;m5&#038;m9&#038;m13\\m2&#038;m6&#038;m10&#038;m14\\m3&#038;m7&#038;m11&#038;m15\end{bmatrix}" /><br />
<br />O como una matriz de tipo fila:<br />
<br /><img src="http://l.wordpress.com/latex.php?latex=%5Cbegin%7Bbmatrix%7Dm0%26m1%26m2%26m3%5C%5Cm4%26m5%26m6%26m7%5C%5Cm8%26m9%26m10%26m11%5C%5Cm12%26m13%26m14%26m15%5Cend%7Bbmatrix%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\begin{bmatrix}m0&#038;m1&#038;m2&#038;m3\\m4&#038;m5&#038;m6&#038;m7\\m8&#038;m9&#038;m10&#038;m11\\m12&#038;m13&#038;m14&#038;m15\end{bmatrix}" style="vertical-align:-20%;" class="tex" alt="\begin{bmatrix}m0&#038;m1&#038;m2&#038;m3\\m4&#038;m5&#038;m6&#038;m7\\m8&#038;m9&#038;m10&#038;m11\\m12&#038;m13&#038;m14&#038;m15\end{bmatrix}" /><br />
<br />Matemáticamente es indiferente cómo prefieras interpretarlas, pero recuerda que si utilizas el formato columna debes realizar post-multiplicaciones, y si usas el formato fila pre-multiplicaciones.<br />
<br />Supongamos que tienes una matriz <img src="http://l.wordpress.com/latex.php?latex=R&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="R" style="vertical-align:-20%;" class="tex" alt="R" /> que representa una rotación y la matriz <img src="http://l.wordpress.com/latex.php?latex=T&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="T" style="vertical-align:-20%;" class="tex" alt="T" /> que realiza una traslación, y quieres combinarlas en una matriz <img src="http://l.wordpress.com/latex.php?latex=C&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="C" style="vertical-align:-20%;" class="tex" alt="C" />, de forma que la matriz de trasformación resultante realice primero la rotación y luego la traslación. Si usas el formato fila tendrás que hacer una pre-multiplicación: <img src="http://l.wordpress.com/latex.php?latex=C%3DR%2AT&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="C=R*T" style="vertical-align:-20%;" class="tex" alt="C=R*T" /> (Esto se lee: <em>la matriz <b>R</b> pre-multiplica a la matriz <b>T</b></em>).<br />
Pero si usas el formato columna el orden se invierte ya que es una post-multiplicación: <img src="http://l.wordpress.com/latex.php?latex=C%3DT%2AR&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="C=T*R" style="vertical-align:-20%;" class="tex" alt="C=T*R" /> (Y esto se lee: <em>la matriz <b>R</b> post-multiplica a la matriz <b>T</b></em>).<br />
<br />Otro ejemplo; quieres transformar el vector <img src="http://l.wordpress.com/latex.php?latex=V%3D%5C%7Bx%2Cy%2Cz%2C0%5C%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V=\{x,y,z,0\}" style="vertical-align:-20%;" class="tex" alt="V=\{x,y,z,0\}" /> por la matriz <img src="http://l.wordpress.com/latex.php?latex=M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="M" style="vertical-align:-20%;" class="tex" alt="M" /> para obtener el vector transformado <img src="http://l.wordpress.com/latex.php?latex=V%27&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'" style="vertical-align:-20%;" class="tex" alt="V'" />.<br />
Si la matriz <img src="http://l.wordpress.com/latex.php?latex=M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="M" style="vertical-align:-20%;" class="tex" alt="M" /> es de tipo fila pre-multiplicas: <img src="http://l.wordpress.com/latex.php?latex=V%27%3DV%2AM&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'=V*M" style="vertical-align:-20%;" class="tex" alt="V'=V*M" /><br />
En cambio, si es de tipo columna post-multiplicas: <img src="http://l.wordpress.com/latex.php?latex=V%27%3DM%2AV&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'=M*V" style="vertical-align:-20%;" class="tex" alt="V'=M*V" /><br />
<br />En algebra matricial <b>siempre</b> se multiplican filas por columnas, por lo tanto si la matriz <img src="http://l.wordpress.com/latex.php?latex=M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="M" style="vertical-align:-20%;" class="tex" alt="M" /> es de tipo fila <img src="http://l.wordpress.com/latex.php?latex=V&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V" style="vertical-align:-20%;" class="tex" alt="V" /> y <img src="http://l.wordpress.com/latex.php?latex=V%27&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'" style="vertical-align:-20%;" class="tex" alt="V'" /> deben ser interpretados como un vectores fila, y si <img src="http://l.wordpress.com/latex.php?latex=M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="M" style="vertical-align:-20%;" class="tex" alt="M" /> es de tipo columna entonces <img src="http://l.wordpress.com/latex.php?latex=V&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V" style="vertical-align:-20%;" class="tex" alt="V" /> y <img src="http://l.wordpress.com/latex.php?latex=V%27&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'" style="vertical-align:-20%;" class="tex" alt="V'" /> deberán ser interpretados como vectores columna.<br />
<br />Un último ejemplo; transforma el vector <img src="http://l.wordpress.com/latex.php?latex=V&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V" style="vertical-align:-20%;" class="tex" alt="V" /> por las matrices <img src="http://l.wordpress.com/latex.php?latex=A%2CB%2CC&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="A,B,C" style="vertical-align:-20%;" class="tex" alt="A,B,C" /> (en éste orden).<br />
La pre-multiplicación sigue el orden natural de las transformaciones por lo que resulta más intuitiva: <img src="http://l.wordpress.com/latex.php?latex=V%27%3DV%2AA%2AB%2AC&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'=V*A*B*C" style="vertical-align:-20%;" class="tex" alt="V'=V*A*B*C" /><br />
La post-multiplicación sería el proceso inverso: <img src="http://l.wordpress.com/latex.php?latex=V%27%3DC%2AB%2AA%2AV&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'=C*B*A*V" style="vertical-align:-20%;" class="tex" alt="V'=C*B*A*V" /><br />
<br />Para terminar un truco para no liarte; cuando utilices matrices y vectores columna (post-multiplicación) debes interpretar las transformaciones como series de funciones: <img src="http://l.wordpress.com/latex.php?latex=V%27%3DC%28B%28A%28V%29%29%29&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="V'=C(B(A(V)))" style="vertical-align:-20%;" class="tex" alt="V'=C(B(A(V)))" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/08/formato-interno-de-las-matrices-en-opengl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Declaraciones complejas en C/C++</title>
		<link>http://www.neptalium.com/blog/2009/06/declaraciones-complejas-en-cpp/</link>
		<comments>http://www.neptalium.com/blog/2009/06/declaraciones-complejas-en-cpp/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 17:01:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Declaraciones Complejas]]></category>
		<category><![CDATA[typedef]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=269</guid>
		<description><![CDATA[Aunque parezca sorprendente muy pocos programadores pueden entender una declaración como ésta: int *const&#40;*&#40;*&#40;*dec&#41;&#40;&#41;&#41;&#91;64&#93;&#41;&#40;int &#40;*&#41;&#40;void *&#41;, double&#91;10&#93;&#41;; No es extraño que sea poco comprensible ya que las declaraciones en C y C++ mezclan operadores que se evalúan de forma infija con otros de evaluación postfija, para el compilador esto no supone ningún problema pero para [...]]]></description>
			<content:encoded><![CDATA[<p>Aunque parezca sorprendente muy pocos programadores pueden entender una declaración como ésta:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span><span style="color: #0000ff;">const</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>dec<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">64</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>, <span style="color: #0000ff;">double</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>No es extraño que sea poco comprensible ya que las declaraciones en C y C++ mezclan operadores que se evalúan de forma infija con otros de evaluación postfija, para el compilador esto no supone ningún problema pero para los programadores sí.<br />
El truco está en interpretarlas tal y como lo hace el compilador; <strong>a partir del identificador avanzar hacia la derecha siempre que sea posible, y si no lo es, avanzar hacia la izquierda.</strong><br />
<br />
Quedará más claro con un ejemplo mucho más simple:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">float</span> <span style="color: #000040;">*</span>var<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></div></div>
<p>¿Qué representa <strong>var</strong>?, ¿es un puntero a un array de floats, o es un array de punteros a float?<br />
Es un array de punteros a float: </p>
<li> A partir del identificador <strong>var</strong> avanzamos hacia la derecha y nos encontramos con <strong>[]</strong> (<strong>var es un array&#8230;</strong>).
<li> No podemos seguir avanzando hacia la derecha, entonces lo hacemos hacia la izquierda y nos encontramos con <strong>*</strong> (<strong>var es un array de punteros&#8230;</strong>) y luego con <strong>float</strong> (<strong>var es un array de punteros a float</strong>).<br />
<br />
Otro ejemplo muy simple:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">double</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>op<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<li> A partir del identificador <strong>op</strong> avanzamos hacia la derecha y nos encontramos con <strong>)</strong> (cierre de paréntesis), por lo que el avance <em>rebota</em> hacia la izquierda y&#8230;
<li> Nos encontramos con <strong>*</strong> (<strong>op es un puntero&#8230;</strong>) y luego con <strong>(</strong> por lo que el avance vuelve a rebotar y ahora avanzamos hacia la derecha y&#8230;
<li> Nos encontramos con <strong>(int)</strong> (<strong>op es un puntero de función que recibe un int&#8230;</strong>), ya no podemos avanzar más hacia la derecha, por lo que volvemos hacia la izquierda y&#8230;
<li> Encontramos un <strong>*</strong> (<strong>op es un puntero de función que recibe un int y devuelve un puntero&#8230;</strong>), seguimos hacia la izquierda y&#8230;
<li> Finalmente encontramos a <strong>double</strong> y <strong>const</strong>, (<strong>op es un puntero de función que recibe un int y devuelve un puntero a double constante</strong>).<br />
<br />
¿Qué pasaría si eliminamos los paréntesis?</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">double</span> <span style="color: #000040;">**</span>op<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>Pues que la declaración cambia totalmente y ahora <strong>op es una función que recibe un int y que devuelve un puntero de puntero a double constante</strong>. ¿A que ahora ya entiendes el porqué de los paréntesis en las declaraciones de punteros de función <strong>(*)()</strong>?<br />
<br />
Vamos a ver ahora el primer ejemplo que he puesto:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span><span style="color: #0000ff;">const</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>dec<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">64</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>, <span style="color: #0000ff;">double</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<li> A partir del identificador <strong>dec</strong> avanzamos hacia la derecha y nos encontramos con <strong>)</strong> por lo que el avance rebota hacia la izquierda y&#8230;
<li> Encontramos <strong>*</strong> (<strong>dec es un puntero&#8230;</strong>) y luego con <strong>(</strong> por lo que el avance vuelve a rebotar y ahora avanzamos hacia la derecha y&#8230;
<li> Encontramos <strong>()</strong> (<strong>dec es un puntero de función&#8230;</strong>), seguimos hacia la derecha y encontramos <strong>)</strong>, volvemos hacia la izquierda&#8230;
<li> Encontramos <strong>*</strong> (<strong>dec es un puntero de función que devuelve un puntero&#8230;</strong>), a continuación encontramos otro <strong>(</strong> por lo que volvemos hacia la derecha y&#8230;
<li> Encontramos <strong>[64]</strong> (<strong>dec es un puntero de función que devuelve un puntero a un array de 64&#8230;</strong>), ahora encontramos otro <strong>)</strong>, volvemos a la izquierda y&#8230;
<li> Encontramos <strong>*</strong> (<strong>dec es un puntero de función que devuelve un puntero a un array de 64 punteros&#8230;</strong>), seguimos hacia la izquierda y encontramos <strong>(</strong>, volvemos hacia la derecha y&#8230;
<li> Encontramos <strong>(int (*)(void *), double[10])</strong> (<strong>dec es un puntero de función que devuelve un puntero a un array de 64 punteros de función que reciben un puntero de función (que a su vez recibe como primer parámetro un puntero de función que devuelve int y recibe un puntero void, y recibe como segundo parámetro un array de 10 doubles)&#8230;</strong>), hacia la derecha ya no podemos avanzar más, volvemos hacia la izquierda y&#8230;
<li> Finalmente encontramos <strong>const</strong>, <strong>*</strong> y luego <strong>int</strong> (<strong>dec es un puntero de función que devuelve un puntero a un array de 64 punteros de función que reciben un puntero de función (que a su vez recibe como primer parámetro un puntero de función que devuelve int y recibe un puntero void, y recibe como segundo parámetro un array de 10 doubles) y que devuelven un puntero constante a int</strong>)<br />
<br />
Al principio dije que las declaraciones se comienzan a leer a partir del identificador, pero ¿qué pasa cuando hay más de uno?</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span><span style="color: #0000ff;">const</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>a<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>b<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">long</span> c, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> <span style="color: #000040;">&amp;</span>d<span style="color: #008000;">&#41;</span></div></div>
<p>En ésta declaración tenemos cuatro identificadores; <strong>a, b, c</strong> y <strong>d</strong>. ¿Por cuál se empieza? Debes fijarte que <strong>b, c</strong> y <strong>d</strong> están realmente declarando parámetros de función, por lo tanto se comienza por <strong>a</strong> (<strong>a es una función que recibe (char *b) y devuelve un puntero de función que recibe (long c, const int &#038;d) y que devuelve un puntero constante a int</strong>).<br />
<br />
Veamos un último ejemplo:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">char</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>extra<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">32</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">float</span> <span style="color: #000040;">&amp;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">16</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></div></div>
<li> A partir de <strong>extra</strong> vamos hacia la derecha y encontramos <strong>[32]</strong> (<strong>extra es un array de 32&#8230;</strong>), seguimos y encontramos <strong>)</strong>, cambiamos hacia al izquierda&#8230;
<li> Encontramos <strong>*</strong> (<strong>extra es un array de 32 punteros&#8230;</strong>), seguimos hacia la izquierda y encontramos <strong>(</strong>, cambiamos hacia la derecha&#8230;
<li> Encontramos <strong>(const float &#038;)</strong> (<strong>extra es un array de 32 punteros de función que reciben una referencia a float constante&#8230;</strong>), seguimos hacia la derecha y nos encontramos con <strong>)</strong>, cambiamos hacia la izquierda&#8230;
<li> Encontramos <strong>*</strong> (<strong>extra es un array de 32 punteros de función que reciben una referencia a float constante y devuelven un puntero&#8230;</strong>), seguimos hacia la izquierda y encontramos <strong>(</strong>, cambiamos hacia la derecha y&#8230;
<li> Encontramos [16] (<strong>extra es un array de 32 punteros de función que reciben una referencia a float constante y devuelven un puntero a un array de 16&#8230;</strong>), ya no podemos seguir más hacia la derecha, volvemos a la izquierda&#8230;
<li> Encontramos <strong>char</strong> (<strong>extra es un array de 32 punteros de función que reciben una referencia a float constante y devuelven un puntero a un array de 16 chars&#8230;</strong>).<br />
<br />
El hecho de que puedas crear y entender declaraciones de cualquier grado de complejidad no significa que debas hacerlo. Es siempre recomendable intentar no complicarlas demasiado y, si no queda más remedio, simplificarlas usando alias con <strong>typedef</strong>. Aquí unos ejemplos muy desglosados:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>I<span style="color: #008080;">;</span></div></div>
<p><strong>I</strong> es un puntero a int.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> I J<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></div></div>
<p><strong>J</strong> es un array de punteros a int.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> J K<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p><strong>K</strong> es una función que devuelve un array de punteros a int.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> K <span style="color: #000040;">*</span>X<span style="color: #008080;">;</span></div></div>
<p><strong>X</strong> es un puntero a una función que devuelve un array de punteros a int.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">bool</span> Y<span style="color: #008000;">&#40;</span>X<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p><strong>Y</strong> es una función que devuelve un bool y recibe un puntero de función que devuelve un array de punteros a int.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> Y <span style="color: #000040;">*</span>Z<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></div></div>
<p><strong>Z</strong> es un array de 10 punteros de función que devuelven bool y reciben un puntero de función que devuelve un array de punteros a int.<br />
<br />
Declarando una variable <strong>var</strong> a partir del alias <strong>Z</strong> esta sería su declaración:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Z var<span style="color: #008080;">;</span> <span style="color: #666666;">// Esto es equivalente a declarar: bool (*var[10])(int *(*)()[])</span></div></div>
<p>
Es evidente que usando <strong>typedef</strong> la declaración es mucho más simple que hacer declaraciones complejas directamente. Aunque hay que tener en cuenta que este es un ejemplo y en realidad no es ni mucho menos necesario declarar el alias <strong>Z</strong> usando seis <strong>typedef</strong>s tan simples, se podría haber declarado usando solamente dos, tres&#8230; los que se consideren necesarios&#8230; o incluso sólo una:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">bool</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>Z<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></div>
<p>El uso correcto de <strong>typedef</strong> es esencial para mantener un código lo más sencillo y claro posible, porque sino, entre otras cosas, puede pasar ésto: </p>
<p style="text-align: justify;"><img class="size-full wp-image-53  alignnone" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/tirar_pc.gif" alt=""/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/06/declaraciones-complejas-en-cpp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Raíz cuadrada, optimización redonda</title>
		<link>http://www.neptalium.com/blog/2009/05/raiz-cuadrada-optimizacion-redonda/</link>
		<comments>http://www.neptalium.com/blog/2009/05/raiz-cuadrada-optimizacion-redonda/#comments</comments>
		<pubDate>Thu, 07 May 2009 17:36:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Computer Graphics]]></category>
		<category><![CDATA[Matemáticas]]></category>
		<category><![CDATA[Fast InvSqrt]]></category>
		<category><![CDATA[Optimización Raíz Cuadrada]]></category>
		<category><![CDATA[Raíz Cuadrada Inversa]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=197</guid>
		<description><![CDATA[En programación 3D hay pocas funciones tan necesarias como la raíz cuadrada. ¿Quién no recuerda el famoso teorema de Pitágoras? El cuadrado de la hipotenusa es igual a la suma de los cuadrados de los catetos por lo tanto la hipotenusa será Esto lo podemos emplear con cualquier número de dimensiones, en 3D tendremos tres [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">En programación 3D hay pocas funciones tan necesarias como la raíz cuadrada. ¿Quién no recuerda el famoso teorema de Pitágoras? El cuadrado de la hipotenusa es igual a la suma de los cuadrados de los catetos <img src="http://l.wordpress.com/latex.php?latex=h%5E%7B2%7D%3Dx%5E%7B2%7D%20%2B%20y%5E%7B2%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="h^{2}=x^{2} + y^{2}" style="vertical-align:-20%;" class="tex" alt="h^{2}=x^{2} + y^{2}" /> por lo tanto la hipotenusa será <img src="http://l.wordpress.com/latex.php?latex=h%3D%5Csqrt%7Bx%5E%7B2%7D%20%2B%20y%5E%7B2%7D%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="h=\sqrt{x^{2} + y^{2}}" style="vertical-align:-20%;" class="tex" alt="h=\sqrt{x^{2} + y^{2}}" /><br />
<br />Esto lo podemos emplear con cualquier número de dimensiones, en 3D tendremos tres coordenas <img src="http://l.wordpress.com/latex.php?latex=%5Cleft%5C%7Bx%2Cy%2Cz%5Cright%5C%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\left\{x,y,z\right\}" style="vertical-align:-20%;" class="tex" alt="\left\{x,y,z\right\}" /> que definen un punto o vector en un espacio tridimensional, aplicando el mismo teorema podemos saber el módulo (longitud) del vector <img src="http://l.wordpress.com/latex.php?latex=m%3D%5Csqrt%7Bx%5E%7B2%7D%2By%5E%7B2%7D%2Bz%5E%7B2%7D%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="m=\sqrt{x^{2}+y^{2}+z^{2}}" style="vertical-align:-20%;" class="tex" alt="m=\sqrt{x^{2}+y^{2}+z^{2}}" /> y a partir del módulo podemos, por ejemplo, normalizarlo (hacer que el vector sea de módulo 1).</p>
<p>Un ejemplo práctico:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">V3 <span style="color: #000040;">&amp;</span>NormalizarVector<span style="color: #008000;">&#40;</span>V3 <span style="color: #000040;">&amp;</span>v<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">float</span> modulo <span style="color: #000080;">=</span> <span style="color: #0000dd;">sqrt</span><span style="color: #008000;">&#40;</span> v.<span style="color: #007788;">x</span><span style="color: #000040;">*</span>v.<span style="color: #007788;">x</span> <span style="color: #000040;">+</span> v.<span style="color: #007788;">y</span><span style="color: #000040;">*</span>v.<span style="color: #007788;">y</span> <span style="color: #000040;">+</span> v.<span style="color: #007788;">z</span><span style="color: #000040;">*</span>v.<span style="color: #007788;">z</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000dd;">assert</span><span style="color: #008000;">&#40;</span>modulo <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color:#800080;">0.0f</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; v.<span style="color: #007788;">x</span> <span style="color: #000040;">/</span><span style="color: #000080;">=</span> modulo<span style="color: #008080;">;</span><br />
&nbsp; v.<span style="color: #007788;">y</span> <span style="color: #000040;">/</span><span style="color: #000080;">=</span> modulo<span style="color: #008080;">;</span><br />
&nbsp; v.<span style="color: #007788;">z</span> <span style="color: #000040;">/</span><span style="color: #000080;">=</span> modulo<span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p style="text-align: justify;">La función anterior para normalizar vectores es perfectamente correcta pero se puede optimizar bastante. En primer lugar calcular raíces cuadradas tiene un coste computacional bastante importante y en aplicaciones 3D como juegos se usa constantemente por lo que es interesante optimizarla todo lo posible. Además de la raíz cuadrada también podemos sustituir las tres divisiones por tres multiplicaciones, ¿cómo lo hacemos? usando la inversa de la raíz cuadrada <img src="http://l.wordpress.com/latex.php?latex=%5Cfrac%7B1%7D%7B%5Csqrt%7Bx%7D%7D&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="\frac{1}{\sqrt{x}}" style="vertical-align:-20%;" class="tex" alt="\frac{1}{\sqrt{x}}" /> que nos permitirá multiplicar en lugar de dividir ya que la división está implícita en el cálculo.<br />
<br />¿Y cómo optimizamos la raíz cuadrada? Existen muchas formas de hacerlo pero vamos a ver la más rápida y sencilla, la raíz cuadrada inversa rápida (<em>Fast InvSqrt</em>):</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">float</span> InvSqrt <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span> x<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">float</span> x_div2 <span style="color: #000080;">=</span> x <span style="color: #000040;">*</span> <span style="color:#800080;">0.5f</span><span style="color: #008080;">;</span>   &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// Dividimos x entre 2</span><br />
&nbsp; <span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;</span>x<span style="color: #008080;">;</span>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// Pasamos de float a int (ambos de 32 bits)</span><br />
&nbsp; i <span style="color: #000080;">=</span> <span style="color: #208080;">0x5f3759df</span> <span style="color: #000040;">-</span> <span style="color: #008000;">&#40;</span>i <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> &nbsp; &nbsp;  &nbsp;<span style="color: #666666;">// Hacemos una primera aproximación del resultado</span><br />
&nbsp; x <span style="color: #000080;">=</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">float</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;</span>i<span style="color: #008080;">;</span>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// Pasamos de int a float</span><br />
&nbsp; x <span style="color: #000080;">=</span> x <span style="color: #000040;">*</span> <span style="color: #008000;">&#40;</span><span style="color:#800080;">1.5f</span> <span style="color: #000040;">-</span> x_div2 <span style="color: #000040;">*</span> x <span style="color: #000040;">*</span> x<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Recalculamos para aproximar más el resultado</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>x<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p style="text-align: justify;">Esta función se aprovecha de la forma interna de trabajo de la unidad de punto flotante (normativa IEEE 754)  para calcular una buena aproximación del resultado exacto. No es más que una simple aproximación por el método Newton.<br />
Este código se hizo muy popular por haber sido utilizado en el <em>Quake 3</em> y aunque su origen no está nada claro parece que surgió de SGI (<em>Silicon Graphics</em>) hace bastantes años.<br />
<br />La nueva función de normalización vectorial quedaría de la siguiente manera:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">V3 <span style="color: #000040;">&amp;</span>NormalizarVector<span style="color: #008000;">&#40;</span>V3 <span style="color: #000040;">&amp;</span>v<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; <span style="color: #0000ff;">float</span> m <span style="color: #000080;">=</span> InvSqrt<span style="color: #008000;">&#40;</span> v.<span style="color: #007788;">x</span><span style="color: #000040;">*</span>v.<span style="color: #007788;">x</span> <span style="color: #000040;">+</span> v.<span style="color: #007788;">y</span><span style="color: #000040;">*</span>v.<span style="color: #007788;">y</span> <span style="color: #000040;">+</span> v.<span style="color: #007788;">z</span><span style="color: #000040;">*</span>v.<span style="color: #007788;">z</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<br />
&nbsp; v.<span style="color: #007788;">x</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> m<span style="color: #008080;">;</span><br />
&nbsp; v.<span style="color: #007788;">y</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> m<span style="color: #008080;">;</span><br />
&nbsp; v.<span style="color: #007788;">z</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> m<span style="color: #008080;">;</span><br />
<br />
&nbsp; <span style="color: #0000ff;">return</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p style="text-align: justify;">El incremento de velocidad conseguido es muy importante pero también hay que tener en cuenta que el resultado es una aproximación y que este código sólo puede usarse en procesadores cuyas unidades de punto flotante sigan la normativa IEEE 754.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/05/raiz-cuadrada-optimizacion-redonda/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>En ocasiones veo tanques&#8230;</title>
		<link>http://www.neptalium.com/blog/2009/02/en-ocasiones-veo-tanques/</link>
		<comments>http://www.neptalium.com/blog/2009/02/en-ocasiones-veo-tanques/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 03:05:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Inteligencia Artificial]]></category>
		<category><![CDATA[Redes Neuronales]]></category>
		<category><![CDATA[Tanques]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=144</guid>
		<description><![CDATA[Crear y entrenar correctamente RNAs (Redes Neuronales Artificiales) tiene más de arte que de ciencia. En primer lugar debes decidir el tipo de red más apropiada para el trabajo que debe realizar (Backpropagation, Hopfield, Adaline, Kohonen, Perceptrón Multicapa, máquina de Boltzman, etc. Incluyendo también la elección de sus funciones de propagación, activación/transferencia) y luego decidir [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Crear y entrenar correctamente RNAs (<em>Redes Neuronales Artificiales</em>) tiene más de arte que de ciencia.</p>
<p style="text-align: center;"><img class="size-full wp-image-153 aligncenter" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/red_neural.jpg" alt="" width="500" height="281" /></p>
<p style="text-align: justify;">En primer lugar debes decidir el tipo de red más apropiada para el trabajo que debe realizar (<em>Backpropagation, Hopfield, Adaline, Kohonen, Perceptrón Multicapa, máquina de Boltzman</em>, etc. Incluyendo también la elección de sus <em>funciones de propagación, activación/transferencia</em>) y luego decidir su topología (<em>monocapa, multicapa o recurrente</em>), después viene su entrenamiento (con <em>aprendizaje supervisado o no supervisado</em>) para lo cual debes escoger una buena selección de ejemplos del problema que deba resolver y entrenarla lo justo y necesario para que <em>entienda</em> el problema correctamente en lugar de simplemente memorizar los ejemplos que ha visto durante su entrenamiento. O lo que puede ser aún peor; que <em>entienda</em> el problema de una forma completamente distinta a la que tu esperas&#8230; <img class="alignnone size-full wp-image-44" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/chicle.gif" alt="" width="64" height="55" /> &#8230;bueno, lo cierto es que siempre lo <em>entienden</em> como les da la gana, y como casi todo en IA una pequeña dosis de caos es esencial.</p>
<p style="text-align: justify;">Para cada problema es necesario encontrar la mejor elección de su tipología (tipo de red), topología (número de capas y número de neuronas por capa -en el caso de redes multicapa-), cuál es la estructura y codificación de la información de entrada y salida que sea más adecuada; muestras y método de entrenamiento, tipo de función de transferencia&#8230;<br />
Si diseñas una red demasiado grande para el problema a tratar  o la sobreentrenas lo único que hará será memorizar las muestras de entrenamiento, si es demasiado pequeña o no has escogido una buena y variada selección de muestras no logrará <em>entenderlo</em> o lo hará de una forma parcial. No te queda otra que probar y probar hasta encontrar el balance ideal para que la red pueda generalizar en base a su entrenamiento.</p>
<p style="text-align: justify;">Toda su <em>inteligencia</em> reside en el <em>peso</em> de sus conexiones, en el caso de las redes multicapa, cada neurona recibe las señales de las neuronas de la capa anterior, multiplica cada señal por el peso asociado a cada conexión y hace un sumatorio de todas, si su valor es positivo la neurona <em>excitará</em> a las neuronas de la siguiente capa y si es negativo las <em>inhibirá</em>. A ésto se le denomina como <em>función de propagación</em>.<br />
Generalmente se programa también una <em>función de activación o transferencia</em>, que sirve para normalizar la salida de la función de propagación dentro de un intervalo determinado, las más utilizadas son:</p>
<ul>
<li><span style="color: #993300;"><strong>Sigmoidea</strong></span><span style="color: #993300;">: 1/1+exp(-x) (para un intervalo de 0 a 1).</span></li>
<li><span style="color: #993300;"><strong>Tangente hiperbólica</strong></span><span style="color: #993300;">:  tanh(x) (para un intervalo de -1 a 1).</span></li>
</ul>
<p style="text-align: justify;">Es también habitual realizar un escalamiento de la salida de la función de activación simplemente multicándolo por un valor de escala más la suma de un valor de desplazamiento. Integrándolo directamente en las funciones de activación que he puesto de ejemplo quedarían así:</p>
<ul>
<li><span style="color: #000080;"><strong><span style="color: #993300;">Sigmoidea</span></strong></span><span style="color: #993300;">: 1/1+exp(-2*s*(x+t))</span></li>
<li><span style="color: #000080;"><strong><span style="color: #993300;">Tangente hiperbólica</span></strong></span><span style="color: #993300;">: tanh(s*(x+t))</span></li>
</ul>
<p>Siendo <strong>x</strong> el valor de entrada, <strong>s</strong> la escala y <strong>t</strong> el desplazamiento.</p>
<ul>
<p style="text-align: center;"><img class="alignnone size-full wp-image-146" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/red_neural.gif" alt="" width="500" height="298" /></p>
<p style="text-align: center;"><em>Ejemplo de una red Perceptrón Multicapa (MLP) de 3 capas; una de entrada de 27 neuronas,<br />
una capa oculta de 22 y una capa de salida con una neurona. Haciendo un total de 13.090 conexiones sinápticas.</em></p>
<p style="text-align: justify;">Y ahora el mejor ejemplo de cómo las RNAs hacen lo que les da la gana. En los 80 los militares norteamericanos se gastaron un buen montón de millones de dólares en un proyecto para incorporar en sus tanques un sistema de detección de tanques enemigos. El sistema consistía en una cámara conectada a un ordenador que iba analizando constantemente las imágenes y avisaba en el caso de que detectase un tanque.</p>
<p style="text-align: justify;">Para este problema decidieron usar una red neuronal. La entrenaron con 200 fotografías; 100 fotos de tanques ocultos tras arboledas y 100 de árboles sin tanques. Hasta aquí todo bien, el entramiento funcionó perfectamente y el sistema era capaz de clasificar las fotos del entrenamiento.</p>
<p style="text-align: center;"><img class="size-full wp-image-154 aligncenter" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/tanque.jpg" alt="" width="500" height="160" /></p>
<p style="text-align: justify;">Llegó el momento de probarlo y&#8230; oh! sorpresa! El sistema fallaba por todos lados y no daba ni una! En primer lugar pensaron que había memorizado las fotos de entrenamiento (y por lo tanto estaría intentando recordar en lugar de generalizar), pero después de mucho investigar, comprobar, verificar, analizar <img class="alignnone size-full wp-image-52" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/pensar.gif" alt="" width="47" height="49" /> y gastar pasta, se dieron cuenta de que las 100 fotos con tanques las habían sacado en días nublados y las otras 100 sin tanques en días soleados, la red había aprendido a reconocer lo que era más evidente; el cielo!<br />
Millones de dólares para que un tanque te diga si hace sol&#8230; Ummm, un poco caro, no?</p>
<p style="text-align: justify;"><img class="size-full wp-image-53  alignnone" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/risa.gif" alt="" width="60" height="44" /></p>
<p style="text-align: justify;">Y ahora os dejo con <a href="http://www.20q.net/" target="_blank">un buen ejemplo muy original de una red neuronal</a> de 10 millones de conexiones sinápticas y una tasa de aciertos del 80% que es capaz de <em>adivinar</em> en qué objeto estás pensando con menos de 20 preguntas.</p>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/02/en-ocasiones-veo-tanques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Falsas entrevistas y C++0x</title>
		<link>http://www.neptalium.com/blog/2009/02/falsas-entrevistas-y-cpp0x/</link>
		<comments>http://www.neptalium.com/blog/2009/02/falsas-entrevistas-y-cpp0x/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 19:05:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Bjarne Stroustrup]]></category>
		<category><![CDATA[Draft Standard C++0x]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=29</guid>
		<description><![CDATA[Queda oficialmente inaugurado este pequeño blog, tengo poco tiempo pero intentaré actualizarlo al menos un par de veces por semana. Hace tiempo que tenía ganas de hacer uno pero siempre la falta de tiempo para atenderlo iba posponiendo la idea, ahora he decidido hacerlo pero, como indica su título, pretendo no emplear nunca más de [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Queda oficialmente inaugurado este pequeño blog, tengo poco tiempo pero intentaré actualizarlo al menos un par de veces por semana. Hace tiempo que tenía ganas de hacer uno pero siempre la falta de tiempo para atenderlo iba posponiendo la idea, ahora he decidido hacerlo pero, como indica su título, pretendo no emplear nunca más de 10 minutos para crear cada nueva entrada. Como veis los comentarios están desactivados (al menos de momento) así no quedo de maleducado si no me paro a responderlos ; )</p>
<p style="text-align: justify;">Bromas aparte, no se me ocurre nada mejor para comenzar que dedicarle la primera entrada al <em>padre</em> de C++, Bjarne Stroustrup. Un danés que  ahora enseña ciencias de la computación en la Universidad A&amp;M de Texas pero que se ha pasado la vida trabajando en los laboratorios Bell de AT&amp;T en USA en donde, allá por 1980, creó el primer prototipo de C++ llamado <em>&#8220;C con clases&#8221;</em> y que todavía no era un compilador sino que, por medio del preprocesador, traducía el código a C para poder ser compilado. Posteriormente creó el primer compilador de C++ llamado<em> CFront </em>aunque también seguía generando código C de salida.<br />
Por cierto, el <em>CFront</em> fue programado con el<em> &#8220;C con clases&#8221;</em>&#8230; tiene su punto el asunto; C++ creando a C++. Ala! ya teneis un nuevo <em>koan</em> tipo huevo-gallina.<br />
El resto ya es historia conocida.</p>
<p style="text-align: center;"><em><a><img class="alignnone size-full wp-image-28" title="Bjarne Stroustrup" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/bjarne_stroustrup.jpg" alt="Bjarne Stroustrup" width="432" height="324" /><br />
</a></em><em>Bjarne Stroustrup</em></p>
<p style="text-align: justify;">Hace 10 años comenzó a circular entre los programadores de C++ una <a href="http://artlung.com/smorgasborg/Invention_of_Cplusplus.shtml" target="_blank">supuesta entrevista</a> suya que nos dejó<a><img class="alignnone size-full wp-image-42" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/asombrar.gif" alt="" width="66" height="44" /></a>, estaba claro que tenía que ser una coña pero hasta tal punto llegó la discusión que para confirmarlo y cerrar de una vez el asunto le envié un e-mail y a los 3 minutos justos me responde con:</p>
<blockquote>
<p style="text-align: left;"><em>Hola, </em></p>
<p style="text-align: left;"><em>Claro, es una broma, y de no muy buen gusto por cierto. Por favor visita siempre <a href="http://www.research.att.com/~bs/" target="_blank">mi web personal</a> en donde pongo las entrevistas que me van haciendo.<br />
</em><em>(&#8230;)</em></p></blockquote>
<p style="text-align: left;">Ésta es una de las <em>perlas</em> de aquella mítica y falsa entrevista:</p>
<blockquote>
<p style="text-align: justify;"><span style="color: #000000;"><em>Well, one day, when I was sitting in my office, I thought of this little scheme, which would redress the balance a little.  I thought &#8216;I wonder what would happen, if there were a language so complicated, so difficult to learn, that nobody would ever be able to swamp the market with programmers?&#8217;<br />
Actually, I got some of the ideas from X10, you know, X windows.  That was such a bitch of a graphics system, that it only just ran on those Sun 3/60 things.  They had all the ingredients for what I wanted.  A really ridiculously complex syntax, obscure functions, and pseudo-OO structure.  Even now, nobody writes raw X-windows code.  Motif is the only way to go if you want to retain your sanity.</em></span><em></p>
<p style="text-align: center"><em><span style="color: #999999;">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</span></em></p>
<p style="text-align: justify;"><span style="color: #747474;">Bueno, un día, cuando estaba sentado en mi oficina, pensé sobre este pequeño sistema que compensaría la balanza un poco. Pensé &#8216;Me pregunto ¿qué pasaría si hubiese un lenguaje tan complicado, tan difícil de aprender, que nadie pudiera saturar el mercado de programadores nunca más?&#8217;<br />
En realidad cogí algunas ideas del X10, ya sabes, el X-windows. Era un sistema gráfico tan cabrón que sólo se podía ejecutar en aquellos Sun 3/60. Tenían todos los ingredientes que quería. Un sistema con una sintaxis tan ridículamente compleja, funciones oscuras, y arquitectura pseudo orientada a objetos. Incluso ahora nadie programa directamente código para X-windows. Utilizar Motif es la única manera si no quieres volverte loco.</span></p>
<p></em></p></blockquote>
<p style="text-align: left;">Si nunca habíais oído hablar de esta entrevista y aún no la habeis leído <a title="La falsa entrevista : )" href="http://artlung.com/smorgasborg/Invention_of_Cplusplus.shtml" target="_blank">ya va siendo hora&#8230;</a> os vais a hartar de reir un buen rato.</p>
<p style="text-align: justify;">Bueno, vamos al tema, aquí os dejo con una conferencia que dio hace un par de años sobre <a title="Draft del estándar C++0x" href="http://www.research.att.com/~bs/SC22-N-4411.pdf" target="_blank">el futuro nuevo estándar C++0x</a> que reemplazará al actual <a title="Estándar C++03 completo" href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38110" target="_blank">C++03 (ISO/IEC 14882)</a>:</p>
<p style="text-align: center;"><object width="500" height="400" data="http://video.google.com/googleplayer.swf?docid=-3478907067117491758&amp;hl=es&amp;fs=true" type="application/x-shockwave-flash"><param name="id" value="VideoPlayback" /><param name="src" value="http://video.google.com/googleplayer.swf?docid=-3478907067117491758&amp;hl=es&amp;fs=true" /><param name="allowfullscreen" value="true" /></object></p>
<p style="text-align: left;">PD: Como veis estoy cogiendo un vicio insano con los <em>muñequitos amarillos</em>, los alérgicos/as manténganse a distancia prudencial, no me hago responsable de posibles efectos secundarios de una larga exposición a estos bichos amigos de PI&#8230;</p>
<p style="text-align: center;"><a><img class="size-full wp-image-74 aligncenter" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/hielo.gif" alt="" width="60" height="54" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/02/falsas-entrevistas-y-cpp0x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Probando&#8230;</title>
		<link>http://www.neptalium.com/blog/2009/02/probando/</link>
		<comments>http://www.neptalium.com/blog/2009/02/probando/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 22:24:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.neptalium.com/blog/?p=3</guid>
		<description><![CDATA[456...]]></description>
			<content:encoded><![CDATA[<p><strong>Probando&#8230;</strong></p>
<p style="text-align: center;">123<img class="alignnone size-full wp-image-7" src="http://www.neptalium.com/blog/wp-content/uploads/2009/02/the_best2.gif" width="60" height="57" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.neptalium.com/blog/2009/02/probando/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

