<?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>Coder-Studio &#187; cantor</title>
	<atom:link href="http://www.coder-studio.com/blog/tag/cantor/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coder-studio.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 02 Mar 2011 22:17:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Construction de l&#039;Ensemble de Cantor en OCaml</title>
		<link>http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/</link>
		<comments>http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 23:12:36 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[batteries]]></category>
		<category><![CDATA[cantor]]></category>
		<category><![CDATA[included]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[ocaml]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=235</guid>
		<description><![CDATA[Bonsoir, Un billet à propos d'OCaml, encore. Je me suis amusé à implémenter la construction de l'Ensemble de Cantor (version anglaise un peu plus complète). Vous voulez en savoir plus ? Première étape, il me fallait une fonction qui à partir d'une liste et d'un couple (a,b) de nombre réels, représentant l'intervalle [a,b], rajoute les [...]]]></description>
			<content:encoded><![CDATA[<p>Bonsoir,</p>
<p>Un billet à propos d'OCaml, encore. Je me suis amusé à implémenter la construction de <a href="http://fr.wikipedia.org/wiki/Ensemble_de_Cantor">l'Ensemble de Cantor</a> (<a href="http://en.wikipedia.org/wiki/Cantor_set">version anglaise un peu plus complète</a>). Vous voulez en savoir plus ?</p>
<p><center><a href="http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/#more-235"><img src="http://www.developpez.net/forums/u67052-a100-i323.png" alt="Construction de l'Ensemble de Cantor" /></a><br />
<span id="more-235"></span></center></p>
<p>Première étape, il me fallait une fonction qui à partir d'une liste et d'un couple (a,b) de nombre réels, représentant l'intervalle [a,b], rajoute les deux intervalles qui en sont générés par une itéraction de la construction de l'ensemble de Cantor, c'est à dire les intervalles [a, (2a+b)/3] et [(a+2b)/3, b], à la liste. Voici la fonction en question, appelée cantor_step ici :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code7'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2357"><td class="code" id="p235code7"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> cantor_step l <span style="color: #6c6;">&#40;</span>a,b<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span>
 <span style="color: #6c6;">&#40;</span>a, <span style="color: #6c6;">&#40;</span>a <span style="color: #a52a2a;">+.</span> <span style="color: #060;">a</span> <span style="color: #a52a2a;">+.</span> <span style="color: #060;">b</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">/.</span> <span style="color: #c6c;">3</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">::</span> <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>a <span style="color: #a52a2a;">+.</span> <span style="color: #060;">b</span> <span style="color: #a52a2a;">+.</span> <span style="color: #060;">b</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">/.</span> <span style="color: #c6c;">3</span><span style="color: #a52a2a;">.</span>, b<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">::</span> l</pre></td></tr></table></div>

<p>Ensuite, il fallait une fonction qui permettre d'appliquer cette fonction sur une liste de couples (a,b) pour passer d'une liste d'intervalles à une autre, c'est à dire passer à l'étape suivante de la génération de l'Ensemble de Cantor. J'ai par la même occasion profité pour rajouté un paramètre n permettant de réaliser cela n fois. J'ai appelé cette fonction map_n.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code8'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2358"><td class="code" id="p235code8"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> map_n f l n <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">match</span> l <span style="color: #06c; font-weight: bold;">with</span>
  <span style="color: #a52a2a;">|</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> <span style="color: #a52a2a;">-&gt;</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span>
  <span style="color: #a52a2a;">|</span> l <span style="color: #a52a2a;">-&gt;</span> aux l n 
      where
	<span style="color: #06c; font-weight: bold;">rec</span> aux l <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span> 
	  <span style="color: #a52a2a;">|</span> <span style="color: #c6c;">0</span> <span style="color: #a52a2a;">-&gt;</span> l
	  <span style="color: #a52a2a;">|</span> k <span style="color: #a52a2a;">-&gt;</span> aux <span style="color: #6c6;">&#40;</span><a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html"><span style="color: #06c; font-weight: bold;">List</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">fold_left</span> f <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> l<span style="color: #6c6;">&#41;</span> <span style="color: #6c6;">&#40;</span>k<span style="color: #a52a2a;">-</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span></pre></td></tr></table></div>

<p>List.fold_left est ce que l'on appelle un "pliage" (<em>fold</em> en Anglais). Pour vous familiariser avec ces derniers, une recherche sur "functional programming fold" devrait vous apporter le nécessaire <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ). Il permet de parcourir la liste d'une certaine façon en appliquant une certaine fonction sur l'élément courant et le résultat de ce qui a été fait jusque là de la même façon, et ainsi de suite. </p>
<p>Enfin, définissons une fonction nth_cantor qui permet d'obtenir la liste des intervalles qui constituent la n-ème itéraction de la construction de l'Ensemble de Cantor.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code9'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2359"><td class="code" id="p235code9"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> nth_cantor <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span>
  <span style="color: #a52a2a;">|</span> <span style="color: #c6c;">0</span> <span style="color: #a52a2a;">-&gt;</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#40;</span><span style="color: #c6c;">0</span><span style="color: #a52a2a;">.</span>,<span style="color: #c6c;">1</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#93;</span>
  <span style="color: #a52a2a;">|</span> k <span style="color: #a52a2a;">-&gt;</span> map_n cantor_step <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#40;</span><span style="color: #c6c;">0</span><span style="color: #a52a2a;">.</span>,<span style="color: #c6c;">1</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#93;</span> k</pre></td></tr></table></div>

<p>On voit donc que l'on part de l'intervalle [0,1], et que l'on va répéter k fois l'itéraction. </p>
<p>Deux fonctions utilitaires, dont une qui utilise non pas le module List standard mais le module List de OCaml Batteries Included, pour la fonction print. (en fait, List.fold_left ci-dessus est également celui de OCaml Batteries Included, étant donné que le programme sera compilé avec OCaml Batteries Included).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code10'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23510"><td class="code" id="p235code10"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> couple_printer <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALoutput"><span style="color: #06c; font-weight: bold;">output</span></a> <span style="color: #6c6;">&#40;</span>a,b<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html"><span style="color: #06c; font-weight: bold;">Printf</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">printf</span> <span style="color: #3cb371;">&quot;(%f,%f)\n&quot;</span> a b
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> list_printer l <span style="color: #a52a2a;">=</span>  <span style="color: #5d478b; font-style: italic;">(* List.print couple_printer stdout l ;*)</span>  <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html"><span style="color: #06c; font-weight: bold;">Printf</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">printf</span> <span style="color: #3cb371;">&quot;\n%d intervals in list\n&quot;</span> <span style="color: #6c6;">&#40;</span><a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html"><span style="color: #06c; font-weight: bold;">List</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">length</span> l<span style="color: #6c6;">&#41;</span></pre></td></tr></table></div>

<p>La première permet d'afficher un couple de réels depuis ... un couple de réels.<br />
La seconde permet d'afficher une liste en précisant quelle fonction utiliser pour afficher chaque élément. Elle affiche ensuite la taille. Ici, le passage d'affichage des éléments est commenté (entre (* ... *)) car ayant testé mon code avec notamment 25 itérations, on se retrouve avec beaucoup trop de choses à afficher pour que ça soit supportable pour un être humain normal.</p>
<p>Enfin, le code qui est exécuté :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code11'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23511"><td class="code" id="p235code11"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> main <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span> 
  <span style="color: #06c; font-weight: bold;">try</span> 
    <span style="color: #06c; font-weight: bold;">let</span> n <span style="color: #a52a2a;">=</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALint_of_string"><span style="color: #06c; font-weight: bold;">int_of_string</span></a> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Sys.html"><span style="color: #06c; font-weight: bold;">Sys</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">argv</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#40;</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">in</span>
    <span style="color: #06c; font-weight: bold;">let</span> cn <span style="color: #a52a2a;">=</span> nth_cantor n <span style="color: #06c; font-weight: bold;">in</span>
      list_printer cn
  <span style="color: #06c; font-weight: bold;">with</span> _ <span style="color: #a52a2a;">-&gt;</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALprint_endline"><span style="color: #06c; font-weight: bold;">print_endline</span></a> <span style="color: #3cb371;">&quot;Use : ./cantor n, where n is an integer&quot;</span> <span style="color: #a52a2a;">;</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALexit"><span style="color: #06c; font-weight: bold;">exit</span></a> <span style="color: #c6c;">0</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> _ <span style="color: #a52a2a;">=</span> main <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span></pre></td></tr></table></div>

<p>Pour  terminer, la compilation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code12'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23512"><td class="code" id="p235code12"><pre class="shell" style="font-family:monospace;">$ ocamlfind batteries/ocamlopt -o cantor cantor.ml</pre></td></tr></table></div>

<p>(pas d'optimisation ici, si vous les voulez, rajouter -cc -O<em>n</em> après ocamlopt)</p>
<p>Et on exécute :</p>
<blockquote><p>$ time ./cantor 25<br />
33554432 intervals in list</p>
<p>real    0m25.553s<br />
user    0m23.481s<br />
sys     0m2.060s
</p></blockquote>
<p>En activant l'affichage des éléments, sur un petit nombre d'itérations :</p>
<blockquote><p>$ time ./cantor 4<br />
[(0.740741,0.753086)<br />
; (0.765432,0.777778)<br />
; (0.666667,0.679012)<br />
; (0.691358,0.703704)<br />
; (0.962963,0.975309)<br />
; (0.987654,1.000000)<br />
; (0.888889,0.901235)<br />
; (0.913580,0.925926)<br />
; (0.074074,0.086420)<br />
; (0.098765,0.111111)<br />
; (0.000000,0.012346)<br />
; (0.024691,0.037037)<br />
; (0.296296,0.308642)<br />
; (0.320988,0.333333)<br />
; (0.222222,0.234568)<br />
; (0.246914,0.259259)<br />
]<br />
16 intervals in list</p>
<p>real    0m0.013s<br />
user    0m0.000s<br />
sys     0m0.016s
</p></blockquote>
<p>Vous avez surement remarqué que cette méthode ne préserve pas l'ordre des intervalles... Ce n'a pas vraiment été mon soucis premier, et ce serait arrangé avec la méthode décrite ci-dessous.</p>
<p>Au passage, si j'utilisais des arbres binaires pour toutes les étapes intermédiaires et que je produisais une liste depuis cet arbre, je gagnerais pas mal en efficacité, disons que je vous le laisse à titre d'exercice <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Enjoy !</p>
<p>PS : la capture d'écran ci-dessus provient d'un programme que j'avais réalisé il y a quelques mois et qui faisait une construction itérative représentée graphiquement, mais la méthode de génération était moins efficace, et j'ai la flemme de refaire la même chose maintenant...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/feed/</wfw:commentRss>
		<slash:comments>1382</slash:comments>
		</item>
	</channel>
</rss>

