<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUYFQXg7fip7ImA9WhRQGUk.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298</id><updated>2011-12-15T12:05:10.606+01:00</updated><category term="C++" /><category term="ruby" /><category term="rozkład normalny" /><category term="gedit" /><category term="java" /><category term="python" /><category term="random number generator" /><category term="php" /><category term="rails" /><category term="normal distribution" /><category term="fibonacci numbers" /><category term="rozkład równomierny" /><category term="Cauchy distribution" /><category term="textmate" /><category term="jruby" /><category term="ubuntu" /><category term="django" /><category term="rozkład Cauchy'ego" /><category term="uniform distribution" /><title>DevZine 0.9 alpha</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://devzine.blogspot.com/" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Devzine09Alpha" /><feedburner:info uri="devzine09alpha" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0QEQ3o7cSp7ImA9WhZTGUs.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-5483531953329826460</id><published>2011-03-24T12:09:00.005+01:00</published><updated>2011-03-24T12:15:02.409+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-24T12:15:02.409+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="django" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Nowe Django 1.3</title><content type="html">&lt;a href="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xc7nEJqTI/AAAAAAAAANI/ivlGclTnGcw/s1600/DjangoLogo-150_79px.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xc7nEJqTI/AAAAAAAAANI/ivlGclTnGcw/s320/DjangoLogo-150_79px.png" /&gt;&lt;/a&gt;Jakiś czas temu (prawie rok) &lt;a href="http://devzine.blogspot.com/2010/05/o-django-w-sdj.html"&gt;pisałem w SDJ o tworzeniu aplikacji internetowych w Django&lt;/a&gt;. Kiedy powstawał ten artykuł, własnie wyszła beta 1.2. Wczoraj ukazała się stabilna wersja 1.3 frameworka a w niej sporo zmian. Pełen opis nowych funkcjonalności tu: &lt;a href="http://docs.djangoproject.com/en/dev/releases/1.3/"&gt;http://docs.djangoproject.com/en/dev/releases/1.3/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Z najważniejszych zmian:&lt;br /&gt;
&lt;br /&gt;
- widoki można tworzyć teraz jako klasy, odpowiednie klasy zastępują też generyczne widoki oparte o funkcje:&amp;nbsp;&lt;a href="http://docs.djangoproject.com/en/dev/topics/generic-views-migration/"&gt;http://docs.djangoproject.com/en/dev/topics/generic-views-migration/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
- logger z poziomu frameworka:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;import logging&lt;br /&gt;
&lt;br /&gt;
logger = logging.getLogger(__name__)&lt;br /&gt;
&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
logger.error('Coś poszło nie tak!')&lt;/blockquote&gt;&lt;br /&gt;
- wygodniejsza obsługa plików statycznych (js, css, obrazki):&amp;nbsp;&lt;a href="http://docs.djangoproject.com/en/dev/howto/static-files/"&gt;http://docs.djangoproject.com/en/dev/howto/static-files/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
- obsługa unittest2&lt;br /&gt;
&lt;br /&gt;
- kontrolowanie zarządzania transakcją w widokach&lt;br /&gt;
&lt;br /&gt;
- konfigurowalne delete-cascade&lt;br /&gt;
&lt;br /&gt;
- ulepszone wbudowane tagi w szablonach&lt;br /&gt;
&lt;br /&gt;
- klasa TemplateResponse&lt;br /&gt;
&lt;br /&gt;
- ulepszona infrastruktura cache'owania&lt;br /&gt;
&lt;br /&gt;
... i wiele innych. Zmiany wprowadzają też częściową niezgodność z poprzednimi wersjami Django.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jak zainstalować najnowszą wersję Django?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Sprawdzamy gdzie w systemie mamy zainstalowane biblioteki dla Pythona&lt;/b&gt;&lt;br /&gt;
&lt;blockquote&gt;$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"&lt;/blockquote&gt;&lt;br /&gt;
w moim wypadku otrzymałem:&lt;br /&gt;
&lt;blockquote&gt;&amp;nbsp;/usr/lib/python2.6/dist-packages&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Ściągamy najnowsze Django&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
a) z SVN'a:&lt;br /&gt;
&lt;br /&gt;
w katalogu gdzie chcemy mieć zawsze najświeższą wersję Django z gałęzi trunk wydajemy polecenie:&lt;br /&gt;
&lt;blockquote&gt;$ svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk&lt;/blockquote&gt;tworzymy dowiązeznie w katalogu z bibliotekami, zamiast SITE-PACKAGES-DIR wpisujemy to co dostaliśmy w kroku 1):&lt;br /&gt;
&lt;blockquote&gt;$ ln -s `pwd`/django-trunk/django SITE-PACKAGES-DIR/django&lt;/blockquote&gt;tworzymy dowiązanie do skryptu administracyjnego:&lt;br /&gt;
&lt;blockquote&gt;$ ln -s `pwd`/django-trunk/django/bin/django-admin.py /usr/local/bin&lt;/blockquote&gt;&lt;br /&gt;
b) z paczki z aktualnym wydaniem:&lt;br /&gt;
&lt;blockquote&gt;$ wget http://media.djangoproject.com/releases/1.3/Django-1.3.tar.gz&lt;br /&gt;
$ tar xzvf Django-1.3.tar.gz&lt;br /&gt;
$ cd Django-1.3&lt;br /&gt;
$ sudo python setup.py install&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;
&lt;b&gt;3. Tworzymy nowy projekt&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$ django-admin.py startproject myproject&lt;br /&gt;
$ cd myproject&lt;br /&gt;
$ python manage.py runserver&lt;/blockquote&gt;&lt;br /&gt;
Efekt:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-994eIItK23Q/TYsk_-1n8ZI/AAAAAAAAAPM/hM45weJVvL0/s1600/django13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="313" src="https://lh6.googleusercontent.com/-994eIItK23Q/TYsk_-1n8ZI/AAAAAAAAAPM/hM45weJVvL0/s400/django13.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-5483531953329826460?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6o8aFTK3ef4dhVLJr2auFGfbZs8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6o8aFTK3ef4dhVLJr2auFGfbZs8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6o8aFTK3ef4dhVLJr2auFGfbZs8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6o8aFTK3ef4dhVLJr2auFGfbZs8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/q-LCuRKalwc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/5483531953329826460/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=5483531953329826460" title="Komentarze (1)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/5483531953329826460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/5483531953329826460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/q-LCuRKalwc/nowe-django-13.html" title="Nowe Django 1.3" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xc7nEJqTI/AAAAAAAAANI/ivlGclTnGcw/s72-c/DjangoLogo-150_79px.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://devzine.blogspot.com/2011/03/nowe-django-13.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08MQn46cCp7ImA9WhZTE0Q.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-123571960549308328</id><published>2011-03-14T23:34:00.005+01:00</published><updated>2011-03-17T22:04:43.018+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-17T22:04:43.018+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gedit" /><category scheme="http://www.blogger.com/atom/ns#" term="textmate" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>gedit jak TextMate</title><content type="html">Jak powszechnie wiadomo każdy prawdziwy railsowy programista ma Maca, a na nim TextMate'a. Ja prawdziwym railsowym programistą nie jestem, ale lubię jak mi się przyjemnie pracuje. Do szybkiej edycji kodu używam gedit'a - co dodatkowo nie czyni mnie prawdziwym linuksiarzem, skoro nie robię tego w emacsie, względnie vimie ;-) &lt;br /&gt;
&lt;br /&gt;
Krótki przepis jak upiększyć nieco standardowy gnomowy edytor tekstu:&lt;br /&gt;
&lt;br /&gt;
1. Instalacja czcionki Monaco:&lt;br /&gt;
&lt;pre&gt;$ wget http://jorrel.googlepages.com/Monaco_Linux.ttf
$ sudo mkdir /usr/share/fonts/truetype/custom/
$ sudo mv Monaco_Linux.ttf /usr/share/fonts/truetype/custom/
$ sudo fc-cache -f -v
&lt;/pre&gt;&lt;br /&gt;
2. Instalacja tematów:&lt;br /&gt;
&lt;br /&gt;
Repozytorium git z tematami dla gedita:&lt;br /&gt;
&lt;pre&gt;https://github.com/mig/gedit-themes
&lt;/pre&gt;&lt;br /&gt;
Ściągamy paczkę z tematami i przenosimy w odpowiednie miejce:&lt;br /&gt;
&lt;pre&gt;$ wget --no-check-certificate https://github.com/mig/gedit-themes/tarball/master -O gedit-themes.tar.gz
$ sudo tar -xvzf gedit-themes.tar.gz 
$ sudo mv mig-gedit-themes-f9b4314/*.xml /usr/share/gtksourceview-2.0/styles/
&lt;/pre&gt;&lt;br /&gt;
sprzątamy po sobie:&lt;br /&gt;
&lt;pre&gt;$ sudo rmdir --ignore-fail-on-non-empty mig-gedit-themes-f9b4314 
$ sudo rm gedit-themes.tar.gz 
&lt;/pre&gt;&lt;br /&gt;
Mi przypadły do gustu tematy 'Oblivion', 'RailsCast' oraz 'Twilight'. Szczególnie ten ostatni pasuje do mojego pulpitu i motywu 'Ambiance' w Ubuntu.&lt;br /&gt;
&lt;br /&gt;
3. Instalacja dodatkowych wtyczek&lt;br /&gt;
&lt;pre&gt;$ sudo apt-get install gedit-plugins
&lt;/pre&gt;Warto włączyć takie wtyczki wspomagające programowanie jak: 'inteligentne spacje', 'komentowanie kodu', 'osadzony terminal', 'uzupełnianie nawiasów' czy 'wstawki'. Nietrudno znaleźć też w sieci wtyczki dedykowane dla RoR czy Django.&lt;br /&gt;
&lt;br /&gt;
Efekt końcowy:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-I-_KmDAzfNw/TX6XWkEljFI/AAAAAAAAAPE/5I68RteT65k/s1600/gedit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="250" src="http://4.bp.blogspot.com/-I-_KmDAzfNw/TX6XWkEljFI/AAAAAAAAAPE/5I68RteT65k/s400/gedit.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-123571960549308328?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4QoHO3Xw4eBqNW2y8qGbA85YU_c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4QoHO3Xw4eBqNW2y8qGbA85YU_c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4QoHO3Xw4eBqNW2y8qGbA85YU_c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4QoHO3Xw4eBqNW2y8qGbA85YU_c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/o2a10C43G88" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/123571960549308328/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=123571960549308328" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/123571960549308328?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/123571960549308328?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/o2a10C43G88/gedit-jak-textmate.html" title="gedit jak TextMate" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-I-_KmDAzfNw/TX6XWkEljFI/AAAAAAAAAPE/5I68RteT65k/s72-c/gedit.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devzine.blogspot.com/2011/03/gedit-jak-textmate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UDR308eyp7ImA9WxFQF0U.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-3497334341897534189</id><published>2010-05-13T22:42:00.010+02:00</published><updated>2010-05-13T23:14:36.373+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-13T23:14:36.373+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="django" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>O Django w SDJ</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xc7nEJqTI/AAAAAAAAANI/ivlGclTnGcw/s1600/DjangoLogo-150_79px.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xc7nEJqTI/AAAAAAAAANI/ivlGclTnGcw/s320/DjangoLogo-150_79px.png" /&gt;&lt;/a&gt;&lt;/div&gt;Majowy numer Software Developer's Journal poświęcony niemalże w całości Pythonowi. Co w nim ciekawego?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Buildout - tworzenie wersji instalacyjnych dla aplikacji napisanych w Pythonie&lt;/li&gt;
&lt;li&gt;Plone - jak zbudować firmowy intranet w oparciu o pythonowy CMS&lt;/li&gt;
&lt;li&gt;Python 3 - co nowego w trzeciej wersji&lt;/li&gt;
&lt;li&gt;Funkyload - testy wydajnościowe w Pythonie&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Ponadto o przetwarzaniu obrazów, programowaniu w Qt 4.5 oraz... o tworzeniu aplikacji internetowych w &lt;b&gt;Django&lt;/b&gt; autorstwa mojej skromnej osoby.&lt;br /&gt;
&lt;br /&gt;
Oprócz o podstawach tworzenia projektu w tym frameworku piszę trochę o wbudowanym mechanizmie uwierzytelniania i autoryzacji. Cały numer można zakupić lub... ściągnąć za darmo&lt;sup&gt;*&lt;/sup&gt; ze strony magazynu SDJ :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sdjournal.org/magazine/1074-nie-trzymaj-weza-w-kieszeni-czyli-co-mozna-zrobic-z-pythonem" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xgzDzb2OI/AAAAAAAAANQ/eYQoj4m1DxA/s320/05_2010_www.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;A teraz troszkę muzyki... Utwór Django Reinhardt'a w wykonaniu Latches:&lt;/div&gt;&lt;br /&gt;
&lt;object width="400" height="360"&gt;&lt;param name="movie" value="http://www.youtube.com/v/B6uXGSTfz_4&amp;hl=pl_PL&amp;fs=1&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/B6uXGSTfz_4&amp;hl=pl_PL&amp;fs=1&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="360"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;br /&gt;
* - w cenie podania swojego adresu e-mail ;-P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-3497334341897534189?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mvqonadTV4nnX9bSzEACZ72GW7g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mvqonadTV4nnX9bSzEACZ72GW7g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mvqonadTV4nnX9bSzEACZ72GW7g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mvqonadTV4nnX9bSzEACZ72GW7g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/R9aT2J8eDfs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/3497334341897534189/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=3497334341897534189" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/3497334341897534189?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/3497334341897534189?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/R9aT2J8eDfs/o-django-w-sdj.html" title="O Django w SDJ" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_k6vqKQCQSW0/S-xc7nEJqTI/AAAAAAAAANI/ivlGclTnGcw/s72-c/DjangoLogo-150_79px.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devzine.blogspot.com/2010/05/o-django-w-sdj.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAERXc-fSp7ImA9WxBVE08.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-1725913917035991326</id><published>2010-02-16T00:54:00.136+01:00</published><updated>2010-02-16T14:58:24.955+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-16T14:58:24.955+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="jruby" /><category scheme="http://www.blogger.com/atom/ns#" term="fibonacci numbers" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="php" /><title>Mythbusters: Java jest wolna?</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_k6vqKQCQSW0/S3nSa8Mg43I/AAAAAAAAAK4/n_mg3geg4OM/s1600-h/jruby.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_k6vqKQCQSW0/S3nSa8Mg43I/AAAAAAAAAK4/n_mg3geg4OM/s320/jruby.png" /&gt;&lt;/a&gt;&lt;/div&gt;Jeszcze raz usłyszę w dyskusji o wyższości jednego języka programowania nad drugim od jakiegoś domorosłego programisty, że Java ssie, bo jest masakrycznie wooolnaaa, to osobiście od siły argumentów przejdę do argumentów siły i wyklepię mu maskę. Owszem, Java ssie, ale z zupełnie innych powodów ;-) Ale o tym kiedy indziej, teraz oddaję głos ekspertom:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" height="225" src="http://2.bp.blogspot.com/_k6vqKQCQSW0/S3nUmkgQ8mI/AAAAAAAAALA/tjGQ3qqAhgs/s400/mythbusters.png" width="400" /&gt;&lt;/div&gt;&lt;br /&gt;
Adam: &lt;i&gt;Hej, Jamie, słyszałeś ten popularny mit krążący wśród programistów, że Java jest wolna?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Jamie: &lt;i&gt;Jasne, ciekawe, że opinię taką wygłaszają ludzie którzy najczęściej nigdy nie napisali w tym języku ani linijki kodu...&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Adam: &lt;i&gt;No ale przecież niż prostszego niż napisać kod w paru językach robiący to samo i sprawdzić który szybciej się wykona?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Jamie: &lt;i&gt;Pewnie! To do roboty, ale wysadzimy coś przy okazji?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bierzemy do porównania: Javę 1.6, Pythona 2.6, Ruby 1.9 (a co, 'podobno' duuużooo szybszy niż 1.8), JRuby 1.4 (no co ty? język skryptowy odpalany w maszynie wirtualnej Javy, to dopiero musi obsysać) i na dokładkę PHP 5.2...&lt;br /&gt;
&lt;br /&gt;
To wszystko odpalimy na maszynie z systemem Ubuntu 9.10 64-bit. Parametry: AMD Athlon 64 X2 Dual Core 4200+, 2GB RAM.&lt;br /&gt;
&lt;br /&gt;
Algorytmem testującym będzie algorytm rekurencyjny obliczający kolejne liczby &lt;a href="http://pl.wikipedia.org/wiki/Ci%C4%85g_Fibonacciego"&gt;ciągu Fibonacciego&lt;/a&gt;. Implementacja wynika wprost z definicji i nie jest to najszybszy algorytm na obliczanie kolejnych liczb tego ciągu (złożoność wykładnicza, istnieje szybszy - liniowy). Nie są to też najszybsze sposoby na zrobienie tego w danym języku, chodzi jednak o to, żeby w każdym z nich zrobić to w 'niemalże' ten sam sposób (na ile pozwala składnia danego języka) ;-).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PYTHON&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;def fib(n):
   if n == 0 or n == 1:
      return n
   else:
      return fib(n-1) + fib(n-2)

for i in range(36):
    print "%d =&amp;gt; %d" % (i, fib(i))
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;RUBY&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;def fib(n)
  if n == 0 || n == 1
    n
  else
    fib(n-1) + fib(n-2)
  end
end

36.times do |i|
  puts "#{i} =&amp;gt; #{fib(i)}"
end
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;JAVA&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;public class Fibonacci {

 public static long fib(int n) {
   if (n == 0 || n == 1) {
    return n;
   } else {
    return fib(n-1) + fib(n-2);
   }
 }

 public static void main(String[] args) {
    for (int i = 1; i &amp;lt; 36; i++) {
       System.out.println(i + " =&amp;gt; " + fib(i));
    }
 }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;PHP&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;function fib($n) {
 if ($n == 0 || $n == 1) {
  return $n;
 } else {
  return fib($n-1) + fib($n-2);
 }
}

for ($i = 1; $i &amp;lt; 36; $i++) {
 echo $i . ' =&amp;gt; ' . fib($i) . "\n";
}&lt;/pre&gt;&lt;br /&gt;
Każdy program odpalę 10 razy i wyciągnę średnią z wyniku. Czas wykonywania zmierzy komenda time.&lt;br /&gt;
&lt;br /&gt;
A oto i uzyskane wyniki (w sekundach):&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;&lt;i&gt;ruby 1.9.1p243 (2009-07-16 revision 24175) [x86_64-linux]&lt;/i&gt;&lt;br /&gt;
&lt;blockquote&gt;17.672, 17.618, 17.615, 17.431, 17.400, 17.409, 17.414, 17.442, 17.498, 17.689&lt;/blockquote&gt;&lt;li&gt;&lt;i&gt;Python 2.6.4:&lt;/i&gt;&lt;br /&gt;
&lt;blockquote&gt;28.776, 28.352, 28.467, 28.268, 28.650, 28.307, 28.768, 28.987, 28.863, 28.278&lt;/blockquote&gt;&lt;li&gt;&lt;i&gt;jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_15) [amd64-java]&lt;/i&gt;&lt;br /&gt;
&lt;blockquote&gt;11.434, 10.885, 11.637, 12.217, 10.686, 11.372, 12.055, 10.704, 11.667, 11.118&lt;/blockquote&gt;&lt;li&gt;&lt;i&gt;Java(TM) SE Runtime Environment (build 1.6.0_15-b03) Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02, mixed mode)&lt;/i&gt;&lt;br /&gt;
&lt;blockquote&gt;0.522, 0.452, 0.442, 0.423, 0.424, 0.423, 0.419, 0.451, 0.446, 0.427&lt;/blockquote&gt;+ czas kompilacji: ~1.2 sek. (jednorazowo)&lt;br /&gt;
&lt;br /&gt;
...i na koniec:&lt;br /&gt;
&lt;li&gt;&lt;i&gt;PHP 5.2.10-2ubuntu6.4 with Suhosin-Patch 0.9.7 (cli) (built: Jan  6 2010 22:56:44)&lt;/i&gt; &lt;br /&gt;
&lt;blockquote&gt;51.864, 52.694, 53.285, 52.890, 52.774, 52.198, 52.209, 52.901, 52.517, 52.174&lt;/blockquote&gt;&lt;br /&gt;
Już widać co i jak, ale jeszcze oficjalna tablica wyników:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;1. Java 1.6 - 0.443 sek.&lt;br /&gt;
2. JRuby 1.4 - 11.377 sek.&lt;br /&gt;
3. Ruby 1.9.1 - 17.519 sek.&lt;br /&gt;
4. Python 2.6.4 - 28.572 sek.&lt;br /&gt;
5. PHP 5.2.10 - 52,551 sek.&lt;/blockquote&gt;&lt;br /&gt;
Tak więc program w Javie wykonał się ponad 100 razy szybciej niż w PHP! Trochę mnie zdziwił Python, miałem nadzieję na wynik w okolicach Rubiego. JRuby okazał się szybszy od swojego brata.&lt;br /&gt;
&lt;br /&gt;
A co z mitem?&lt;br /&gt;
&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_k6vqKQCQSW0/S3nuGy_Xc8I/AAAAAAAAALI/tXzEukn_Eic/s200/busted.png" width="200" /&gt;&lt;br /&gt;
&lt;br /&gt;
P.S. Jak pisałem wcześniej, nie są to najszybsze możliwe algorytmy dla tego zadania. Jaki Ty znasz sposób na jak najwydajniejszy algorytm obliczania ciągu Fibonacciego w swoim ulubionym języku?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-1725913917035991326?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RMIaFIFbTuAXtZ1XRmCYOsZXbjE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RMIaFIFbTuAXtZ1XRmCYOsZXbjE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RMIaFIFbTuAXtZ1XRmCYOsZXbjE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RMIaFIFbTuAXtZ1XRmCYOsZXbjE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/QIr-vyPvals" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/1725913917035991326/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=1725913917035991326" title="Komentarze (13)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/1725913917035991326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/1725913917035991326?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/QIr-vyPvals/mythbusters-java-jest-wolna.html" title="Mythbusters: Java jest wolna?" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_k6vqKQCQSW0/S3nSa8Mg43I/AAAAAAAAAK4/n_mg3geg4OM/s72-c/jruby.png" height="72" width="72" /><thr:total>13</thr:total><feedburner:origLink>http://devzine.blogspot.com/2010/02/mythbusters-java-jest-wolna.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IBR3kzcSp7ImA9WxBbEkk.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-2729237116078606736</id><published>2010-02-09T21:24:00.017+01:00</published><updated>2010-03-10T20:32:36.789+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-10T20:32:36.789+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Rails 3.0 + Ruby 1.9 na Ubuntu 9.10</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_k6vqKQCQSW0/S3HE8k3g3yI/AAAAAAAAAKw/_TCCmja1SFY/s1600-h/rails.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_k6vqKQCQSW0/S3HE8k3g3yI/AAAAAAAAAKw/_TCCmja1SFY/s320/rails.png" /&gt;&lt;/a&gt;&lt;/div&gt;5 lutego ukazała się wersja 3.0 beta środowiska Rails. Pełna notka o wydaniu&amp;nbsp;&lt;a href="http://guides.rails.info/3_0_release_notes.html"&gt;tu&lt;/a&gt;. Wersja ta jest długo oczekiwanym efektem połączenia sił (i kodu) ludzi pracujących nad &lt;a href="http://rubyonrails.org/merb"&gt;Rails i Merb&lt;/a&gt;. Pierwsze pogłoski o merge'u pojawiały się około &lt;a href="http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3"&gt;grudnia 2008&lt;/a&gt;, dziś efekt tych prac biorę sobie na warsztat :)&lt;br /&gt;
&lt;br /&gt;
&lt;div style="clear: left;"&gt;&lt;b&gt;Instalacja w Ubuntu 9.10&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Instalacja w wersji dla leniwych. W systemie zainstalowany zostanie Ruby w wersji 1.9.1 oraz Gems 1.3.5.&lt;br /&gt;
&lt;blockquote&gt;$ sudo apt-get install ruby1.9.1-full&amp;nbsp;rubygems1.9.1&lt;/blockquote&gt;&lt;br /&gt;
jeśli nie mieliśmy wcześniej innych wersji rubiego, podlinkujmy:&lt;br /&gt;
&lt;blockquote&gt;$ sudo ln -s /usr/bin/ruby1.9.1 /usr/bin/ruby&lt;/blockquote&gt;&lt;br /&gt;
Jeśli mieliśmy, zmieńmy ten symlink tak aby wskazywał na najnowszą wersję.&lt;br /&gt;
&lt;br /&gt;
Teraz sprawdźmy co gdzie jest:&lt;br /&gt;
&lt;blockquote&gt;$ gem environment&lt;/blockquote&gt;&lt;br /&gt;
powinniśmy otrzymać coś w tym stylu:&lt;br /&gt;
&lt;blockquote&gt;RubyGems Environment:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- RUBYGEMS VERSION: 1.3.5&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- RUBY VERSION: 1.9.1 (2009-07-16 patchlevel 243) [x86_64-linux]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- INSTALLATION DIRECTORY: /var/lib/gems/1.9.1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- RUBY EXECUTABLE: /usr/bin/ruby1.9.1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- EXECUTABLE DIRECTORY: /var/lib/gems/1.9.1/bin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- RUBYGEMS PLATFORMS:&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;- ruby&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;- x86_64-linux&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- GEM PATHS:&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - /var/lib/gems/1.9.1&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - /home/jasio/.gem/ruby/1.9.1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- GEM CONFIGURATION:&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - :update_sources =&amp;gt; true&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - :verbose =&amp;gt; true&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - :benchmark =&amp;gt; false&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - :backtrace =&amp;gt; false&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - :bulk_threshold =&amp;gt; 1000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- REMOTE SOURCES:&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; - http://gems.rubyforge.org/&lt;/blockquote&gt;&lt;br /&gt;
Teraz do pliku .bashrc dodajmy na koniec lokalizację naszych gemsów:&lt;br /&gt;
&lt;blockquote&gt;$ gedit ~/.bashrc&lt;/blockquote&gt;&lt;br /&gt;
w ostatniej linii dopisujemy:&lt;br /&gt;
&lt;blockquote&gt;export GEM_HOME="/var/lib/gems/1.9.1"&lt;/blockquote&gt;&lt;br /&gt;
Pamiętajmy że zmienna zaistnieje w środowisku po otwarciu nowej konsoli. Ewentualnie wykonajmy powyższe polecenie z palca.&lt;br /&gt;
&lt;br /&gt;
OK. Teraz czas na instalację Railsów i potrzebnych zależności:&lt;br /&gt;
&lt;blockquote&gt;$ sudo&amp;nbsp;gem install tzinfo builder i18n memcache-client rack rake rack-test rack-mount erubis mail text-format thor bundler&lt;br /&gt;
$ sudo gem install rails --pre&lt;/blockquote&gt;&lt;br /&gt;
Podlinkujmy railsy w /usr/bin:&lt;br /&gt;
&lt;blockquote&gt;$ sudo ln -l /var/lib/gems/1.9.1/bin/rails -v /usr/bin/rails&lt;/blockquote&gt;&lt;br /&gt;
Na koniec przydałaby się jakiś przynajmniej sqlite:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$ sudo apt-get install sqlite3 libsqlite3-dev&lt;br /&gt;
$ sudo gem install sqlite3-ruby&lt;/blockquote&gt;&lt;br /&gt;
&lt;b&gt;Hello World!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
OK. Teraz generujemy zalążek aplikacji:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$ rails myapp&lt;br /&gt;
$ cd myapp&lt;br /&gt;
$ rails server&lt;/blockquote&gt;&lt;br /&gt;
&lt;b&gt;... i działa :)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_k6vqKQCQSW0/S3Fp6tZXslI/AAAAAAAAAKo/FkdzgZGIQ20/s1600-h/rails3b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="380" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S3Fp6tZXslI/AAAAAAAAAKo/FkdzgZGIQ20/s400/rails3b.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-2729237116078606736?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mOIVrfvesUppBaPgeAkvvBwNTCg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mOIVrfvesUppBaPgeAkvvBwNTCg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mOIVrfvesUppBaPgeAkvvBwNTCg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mOIVrfvesUppBaPgeAkvvBwNTCg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/SPT5ATpgTxU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/2729237116078606736/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=2729237116078606736" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/2729237116078606736?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/2729237116078606736?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/SPT5ATpgTxU/rails-30-ruby-19-na-ubuntu-910.html" title="Rails 3.0 + Ruby 1.9 na Ubuntu 9.10" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_k6vqKQCQSW0/S3HE8k3g3yI/AAAAAAAAAKw/_TCCmja1SFY/s72-c/rails.png" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://devzine.blogspot.com/2010/02/rails-30-ruby-19-na-ubuntu-910.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cERHs9eSp7ImA9WxVbF0k.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-3847395858050999479</id><published>2009-04-03T09:53:00.009+02:00</published><updated>2009-04-03T10:56:45.561+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-03T10:56:45.561+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rozkład Cauchy'ego" /><category scheme="http://www.blogger.com/atom/ns#" term="Cauchy distribution" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="random number generator" /><title>Generator liczb pseudolosowych (cz.3) - rozkład Cauchy'ego</title><content type="html">Witajcie, zgodnie z obietnicą, w tym odcinku generujemy liczby losowe z &lt;a href="http://pl.wikipedia.org/wiki/Rozk%C5%82ad_Cauchy%27ego"&gt;rozkładu Cauchy'ego&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Jak w &lt;a href="http://devzine.blogspot.com/2009/04/generator-liczb-pseudolosowych-cz2.html"&gt;poprzednim odcinku&lt;/a&gt;, użyjemy generatora rozkładu równomiernego. Kod metody getFromCauchyDistribution() wygląda następująco:&lt;br /&gt;&lt;pre&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; RandomNumberGenerator::getFromCauchyDistribution() {&lt;br /&gt;&lt;br /&gt;    &lt;span class="comment"&gt;// generuj X o rozkładzie równomiernym U(-1,1)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword-directive"&gt;double&lt;/span&gt; X = getFromUniformDistribution() * 2 - 1;&lt;br /&gt;&lt;br /&gt;    &lt;span class="comment"&gt;// generuj X o rozkładzie równomiernym U(0,1)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword-directive"&gt;double&lt;/span&gt; U = getFromUniformDistribution();&lt;br /&gt;&lt;br /&gt;    &lt;span class="keyword-directive"&gt;if&lt;/span&gt; ((U + 0.27324) * (1 + X * X) &amp;gt; 1.27324) {&lt;br /&gt;        X = getFromUniformDistribution() * 2 - 1;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="comment"&gt;// uzupelnienie rozkładu o &amp;quot;ramiona&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword-directive"&gt;if&lt;/span&gt; (getFromUniformDistribution() &amp;gt; 0.5) {&lt;br /&gt;        &lt;span class="keyword-directive"&gt;return&lt;/span&gt; X;&lt;br /&gt;    } &lt;span class="keyword-directive"&gt;else&lt;/span&gt; {&lt;br /&gt;        &lt;span class="keyword-directive"&gt;if&lt;/span&gt; (X != 0) {&lt;br /&gt;            &lt;span class="keyword-directive"&gt;return&lt;/span&gt; (1 / X);&lt;br /&gt;        } &lt;span class="keyword-directive"&gt;else&lt;/span&gt; {&lt;br /&gt;            &lt;span class="keyword-directive"&gt;return&lt;/span&gt; MAXDOUBLE;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;Możemy przerobić nieco program z poprzedniego odcinka generujący dane statystyczne potrzebne do narysowania histogramu. Otrzymane wyniki porównamy z tymi, które dostarczył nam generator rozkładu normalnego.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k6vqKQCQSW0/SdXDWAyMVAI/AAAAAAAAAFs/N8gp0yLFl6M/s1600-h/rozklady.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 394px; height: 343px;" src="http://4.bp.blogspot.com/_k6vqKQCQSW0/SdXDWAyMVAI/AAAAAAAAAFs/N8gp0yLFl6M/s400/rozklady.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5320373317743170562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Jak nietrudno się domyślić, ten pomarańczowy wykres to histogram dla liczb z rozkładu normalnego a niebieski - z Cauchy'ego.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-3847395858050999479?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DGlWAXwCM4jAQK7QHHiVm7Xyf8s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DGlWAXwCM4jAQK7QHHiVm7Xyf8s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DGlWAXwCM4jAQK7QHHiVm7Xyf8s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DGlWAXwCM4jAQK7QHHiVm7Xyf8s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/pxuSSjja6UM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/3847395858050999479/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=3847395858050999479" title="Komentarze (0)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/3847395858050999479?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/3847395858050999479?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/pxuSSjja6UM/generator-liczb-pseudolosowych-cz3.html" title="Generator liczb pseudolosowych (cz.3) - rozkład Cauchy'ego" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_k6vqKQCQSW0/SdXDWAyMVAI/AAAAAAAAAFs/N8gp0yLFl6M/s72-c/rozklady.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://devzine.blogspot.com/2009/04/generator-liczb-pseudolosowych-cz3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8DSX86fSp7ImA9WxJRF0s.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-3688147936008295875</id><published>2009-04-01T10:43:00.030+02:00</published><updated>2009-05-19T23:17:58.115+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-19T23:17:58.115+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="normal distribution" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="rozkład normalny" /><category scheme="http://www.blogger.com/atom/ns#" term="random number generator" /><title>Generator liczb pseudolosowych (cz.2) - rozkład normalny</title><content type="html">&lt;a href="http://devzine.blogspot.com/2009/03/generator-liczb-pseudolosowych.html"&gt;W poprzednim odcinku&lt;/a&gt; otrzymaliśmy całkiem przyzwoity generator liczb o rozkładzie równomiernym. Teraz uzupełnimy naszą klasę o metodę do pobierania wartości z rozkładu normalnego, zwanego też &lt;a href="http://pl.wikipedia.org/wiki/Rozk%C5%82ad_normalny"&gt;rozkładem Gaussa&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Zastosowanym algorytmem do generowania liczb losowych z rozkładu normalnego jest implementacja metody Kindermana i Monahana, zwanej ROU (ratio-of-uniforms method). Szczegóły tej metody można znaleźć w książce Wieczorkowskiego i Zielińskiego[2]&lt;br /&gt;&lt;br /&gt;Moja implementacja w języku C++ zawarta jest w metodzie  getFromNormalDistribution() klasy  RandomNumberGenerator i wygląda następująco:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; RandomNumberGenerator::getFromNormalDistribution(){&lt;br /&gt;&lt;span class="keyword-directive"&gt;bool&lt;/span&gt; ok = &lt;span class="keyword-directive"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; limit = sqrt(2/2.718281828);&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; X;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;do&lt;/span&gt; {&lt;br /&gt;   &lt;span class="comment"&gt;// generuj U o rozkładzie równomiernym U(0,1) &lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; U = getFromUniformDistribution();&lt;br /&gt;   &lt;span class="comment"&gt;// generuj V o rozkładzie równomiernym&lt;/span&gt;&lt;br /&gt;   &lt;span class="comment"&gt;// U(-sqrt(2/e),sqrt(2/e))&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; V = 2 * limit * getFromUniformDistribution() - limit;&lt;br /&gt;   X = V / U;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;if&lt;/span&gt; (X*X &amp;lt;= 2*(3-U*(4+U))) {&lt;br /&gt;       ok = &lt;span class="keyword-directive"&gt;true&lt;/span&gt;;&lt;br /&gt;   } &lt;span class="keyword-directive"&gt;else&lt;/span&gt; &lt;span class="keyword-directive"&gt;if&lt;/span&gt; (X*X &amp;lt;= 2/U - 2*U) {&lt;br /&gt;       &lt;span class="keyword-directive"&gt;if&lt;/span&gt; (X*X &amp;lt;= -4*log(U)) {&lt;br /&gt;           ok = &lt;span class="keyword-directive"&gt;true&lt;/span&gt;;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;} &lt;span class="keyword-directive"&gt;while&lt;/span&gt; (!ok);&lt;br /&gt;&lt;span class="keyword-directive"&gt;return&lt;/span&gt; X;&lt;br /&gt;}&lt;/pre&gt;Jak widać używa on metody getFromUniformDistribution()  zdefiniowanej wcześniej a zwracającej nam dwie liczby z rozkładu rónomiernego, jedna z przedziału (0,1) a druga z &lt;span&gt;&lt;span class="comment"&gt;(-sqrt(2/e), sqrt(2/e))&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ok. Teraz wypadałoby jakoś przetestować nasz generator. Do tego celu napiszemy szybko programik generujący histogram otrzymywanych wartości. Oto on:&lt;pre&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;"source/RandomNumberGenerator.cpp"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;using&lt;/span&gt; &lt;span class="keyword-directive"&gt;namespace&lt;/span&gt; std;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;int&lt;/span&gt; main(&lt;span class="keyword-directive"&gt;int&lt;/span&gt; argc, &lt;span class="keyword-directive"&gt;char&lt;/span&gt;* args[]) {&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;// wektor przechowywujący liczebność wylosowanych liczb w danym przedziale&lt;/span&gt;&lt;br /&gt;vector&amp;lt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt;&amp;gt; histogram;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; min = -3;   &lt;span class="comment"&gt;// dolna granica&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; max = 3;    &lt;span class="comment"&gt;// górna granica&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; n = 1000;   &lt;span class="comment"&gt;// liczba przedziałów&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;// krok o jaki będą zwiększać się kolejne przedziały&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; step = (max - min) / n;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;// zainicjowanie licznikow&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;for&lt;/span&gt; (&lt;span class="keyword-directive"&gt;int&lt;/span&gt; i=0; i &amp;lt; n; i++){&lt;br /&gt;   histogram.push_back(0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;// losowanie i określenie w którym przedziale znajduje się wylosowana liczba&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;for&lt;/span&gt; (&lt;span class="keyword-directive"&gt;int&lt;/span&gt; k=0; k&amp;lt;10000000; k++) {&lt;br /&gt;&lt;br /&gt;   &lt;span class="comment"&gt;// pobranie wartości losowej&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; X = RandomNumberGenerator::Instance()-&gt;getFromUniformDistribution();&lt;br /&gt;&lt;br /&gt;   &lt;span class="comment"&gt;// 'odległość' od dolnej granicy&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; lX = X - min;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;if&lt;/span&gt; ((X &amp;gt;= min) &amp;amp;&amp;amp; (X &amp;lt;= max)){&lt;br /&gt;       &lt;span class="keyword-directive"&gt;int&lt;/span&gt; i = (&lt;span class="keyword-directive"&gt;int&lt;/span&gt;) floor(lX / step);  &lt;span class="comment"&gt;// obliczenie, do którego przedziału zalicza się wylosowana wartość&lt;/span&gt;&lt;br /&gt;       histogram[i] = histogram[i] + 1; &lt;span class="comment"&gt;// zwiększenie licznika danego przedziału&lt;/span&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;// wyprowadzenie wartości liczników na standardowe wyjście&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;for&lt;/span&gt; (&lt;span class="keyword-directive"&gt;unsigned&lt;/span&gt; &lt;span class="keyword-directive"&gt;int&lt;/span&gt; j=0; j &amp;lt; histogram.size(); j++){&lt;br /&gt;   cout &amp;lt;&amp;lt; histogram[j] &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;span class="keyword-directive"&gt;return&lt;/span&gt; EXIT_SUCCESS;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Przekierowując dane ze standardowego wyjścia na plik, można zapisać otrzymane wyniki:&lt;br /&gt;&lt;pre&gt;$ ./RandomGen &gt; stats.txt&lt;/pre&gt;&lt;br /&gt;Teraz statystyki można wsadzić np. do OpenOffice'a i wygenerować histogramy:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_k6vqKQCQSW0/SdU57Psq1jI/AAAAAAAAAFU/flUXUuFD2T8/s400/10tys.png" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 284px;" alt="" id="BLOGGER_PHOTO_ID_5320222224797062706" border="0" /&gt;&lt;br /&gt;Histogram otrzymany dla 10 tys. liczb&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k6vqKQCQSW0/SdU8DtIKnmI/AAAAAAAAAFc/nxrf8GlEvtY/s1600-h/100tys.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 284px;" src="http://4.bp.blogspot.com/_k6vqKQCQSW0/SdU8DtIKnmI/AAAAAAAAAFc/nxrf8GlEvtY/s400/100tys.png" alt="" id="BLOGGER_PHOTO_ID_5320224569159229026" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Histogram dla 100 tys. liczb&lt;br /&gt;&lt;br /&gt;I co, fajnie? :) To teraz zwiększmy liczbę kroków pętli for do... 10 milionów:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_k6vqKQCQSW0/SdU9oyi4unI/AAAAAAAAAFk/8W7iXhx-fG8/s1600-h/10mil.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 284px;" src="http://3.bp.blogspot.com/_k6vqKQCQSW0/SdU9oyi4unI/AAAAAAAAAFk/8W7iXhx-fG8/s400/10mil.png" alt="" id="BLOGGER_PHOTO_ID_5320226305780267634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Całkiem ładny rozkład normalny? To tyle na razie... w następnym odcinku zajmiemy się rozkładem Cauchy'ego...&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[1] &lt;a href="http://pl.wikipedia.org/wiki/Generator_liczb_pseudolosowych"&gt;http://pl.wikipedia.org/wiki/Generator_liczb_pseudolosowych&lt;/a&gt;&lt;br /&gt;[2] &lt;a href="http://www.wnt.pl/product.php?action=0&amp;amp;prod_id=90&amp;amp;hot=1"&gt;"Komputerowe generatory liczb losowych" R. Wieczorkowski R Zieliński, WNT 1997&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:10px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-3688147936008295875?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9wJ_UWvNpWHAXX_vlIqUz41RkYI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9wJ_UWvNpWHAXX_vlIqUz41RkYI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9wJ_UWvNpWHAXX_vlIqUz41RkYI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9wJ_UWvNpWHAXX_vlIqUz41RkYI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/HHJedM11vyM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/3688147936008295875/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=3688147936008295875" title="Komentarze (4)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/3688147936008295875?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/3688147936008295875?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/HHJedM11vyM/generator-liczb-pseudolosowych-cz2.html" title="Generator liczb pseudolosowych (cz.2) - rozkład normalny" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_k6vqKQCQSW0/SdU57Psq1jI/AAAAAAAAAFU/flUXUuFD2T8/s72-c/10tys.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://devzine.blogspot.com/2009/04/generator-liczb-pseudolosowych-cz2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IHSXszcCp7ImA9WxVbF0k.&quot;"><id>tag:blogger.com,1999:blog-3797225076051014298.post-6144051364142146179</id><published>2009-03-30T20:54:00.011+02:00</published><updated>2009-04-03T11:05:38.588+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-03T11:05:38.588+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rozkład równomierny" /><category scheme="http://www.blogger.com/atom/ns#" term="uniform distribution" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="random number generator" /><title>Generator liczb pseudolosowych (cz.1)</title><content type="html">No i stało się... teraz jakoś trzeba zacząć :) Przeglądając zakamarki starego dysku natknąłem się na pewen projekt. Kodzik powstał przy okazji zaliczania Metaheurystyk parę lat temu, a ponieważ wydał mi się ciekawy i dawno nie pisałem już w C++, postanowiłem wyciągnąć go na światło dzienne... Temat stary jak same komputery - generowanie liczb pseudolosowych. Nuda? :) Cóż, niekoniecznie... czasem przydaje się coś nieco bardziej wymyślnego (czyt. o lepszych właściwościach statystycznych) niż klasyczne:&lt;div&gt;&lt;blockquote&gt;#define frand() ((double) rand() / (RAND_MAX+1.0))&lt;/blockquote&gt;To co? Jedziemy ? ;-) Teorii sobie i Wam oszczędzę... dociekliwych i z zacięciem matematycznym odsyłam do tej książeczki [2]. W niej to opisane są poniższe algorytmy. Kod zamieszczam jedynie w celach poznaczych, a studentów WSISIZ przestrzegam przed metodą Kopiego-Paste'a, bo się skończy brakem zaliczenia ;-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Chcemy uzyskać generator o &lt;a href="http://pl.wikipedia.org/wiki/Rozk%C5%82ad_normalny"&gt;rozkładzie normalnym&lt;/a&gt; oraz &lt;a href="http://pl.wikipedia.org/wiki/Rozk%C5%82ad_Cauchy%27ego"&gt;Cauchy'ego&lt;/a&gt;... Na początek jednak jako podstawa potrzebny nam będzie generator o &lt;a href="http://pl.wikipedia.org/wiki/Rozk%C5%82ad_jednostajny"&gt;rozkładzie równomiernym&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Zdefiniujmy sobie klasę RandomNumberGenerator:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span class="keyword-directive"&gt;class&lt;/span&gt; RandomNumberGenerator {&lt;br /&gt;&lt;span class="keyword-directive"&gt;private&lt;/span&gt;:&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; a,b,c;&lt;br /&gt;   &lt;span class="keyword-directive"&gt;static&lt;/span&gt; RandomNumberGenerator* instance;&lt;br /&gt;&lt;span class="keyword-directive"&gt;protected&lt;/span&gt;:&lt;br /&gt;   RandomNumberGenerator();&lt;br /&gt;&lt;span class="keyword-directive"&gt;public&lt;/span&gt;:&lt;br /&gt;   &lt;span class="keyword-directive"&gt;static&lt;/span&gt; RandomNumberGenerator* getInstance();&lt;br /&gt;   &lt;span class="keyword-directive"&gt;void&lt;/span&gt; init();&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; getFromUniformDistribution();&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; getFromNormalDistribution();&lt;br /&gt;   &lt;span class="keyword-directive"&gt;double&lt;/span&gt; getFromCauchyDistribution();&lt;br /&gt;};&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Klasa jak widać będzie miała trzy metody do pobierania losowych wartości z różnych rozkładów. Zaimplementujmy pierwszy rozkład, używając do tego celu tzw. ogólnego generatora liniowego. Generator ten realizuje schemat liniowy:&lt;/div&gt;&lt;div&gt;&lt;p style="margin-bottom: 0cm; font-weight: normal;" align="center"&gt;&lt;span style=""&gt;&lt;span style="font-size:85%;"&gt;&lt;blockquote&gt;X&lt;sub&gt;n+1&lt;/sub&gt; = (a&lt;sub&gt;1&lt;/sub&gt;X&lt;sub&gt;n&lt;/sub&gt; + a&lt;sub&gt;2&lt;/sub&gt;X&lt;sub&gt;n-1&lt;/sub&gt; + ... + a&lt;sub&gt;k&lt;/sub&gt;X&lt;sub&gt;n-k+1&lt;/sub&gt; + c) mod m&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm; font-weight: normal;" align="center"&gt;&lt;span style=""&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;span&gt;Okres tego generatora wynosi 2&lt;sup&gt;96&lt;/sup&gt;, generator spełnia też testy statystyczne &lt;a href="http://en.wikipedia.org/wiki/Diehard_tests"&gt;DIEHARD&lt;/a&gt;, wydaje się więc całkiem OK&lt;/span&gt;&lt;span&gt;&lt;span&gt;. Inicjowany jest trzema nieujemnymi liczbami całkowitymi (zmienne prywatne a,b,c) - można do tego celu użyć funkcji time(), zapewniając różne wyniki za każdym uruchomieniem programu. Ustalenie tych wartości stałymi spowoduje oczywiście generowanie takiego samego ciągu liczb za każdym razem (algorytm jest deterministyczny). Ponieważ znane są metody określania parametrów początkowych na podstawie obserwacji generowanego ciągu, nie jest to algorytm bezpieczny do zastosowań kryptograficznych[1].&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;Przedstawiona w książce Wieczorkowskiego i Zielińskiego[2] implementacja generuje liczby z przedziału (-0.5, 0.5), dostosowałem ją więc tak aby przedział ten wynosił (0,1) - taki, jaki jest potrzebny do późniejszego użycia w generatorze o rozkładzie normalnym. Inicjacja generatora następuje w metodzie init(), a sam algorytm w metodzie getFromUniformDistribution():&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;&amp;lt;values.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;&amp;lt;time.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor-keyword-directive"&gt;#&lt;/span&gt;&lt;span class="preprocessor-keyword-directive"&gt;include&lt;/span&gt; &lt;span class="preprocessor-system-include-literal"&gt;"RandomNumberGenerator.h"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;using&lt;/span&gt; &lt;span class="keyword-directive"&gt;namespace&lt;/span&gt; std;&lt;br /&gt;&lt;br /&gt;RandomNumberGenerator* RandomNumberGenerator::instance = 0;&lt;br /&gt;&lt;br /&gt;RandomNumberGenerator* RandomNumberGenerator::Instance(){&lt;br /&gt;&lt;span class="keyword-directive"&gt;if&lt;/span&gt; (instance == 0){&lt;br /&gt;       instance = &lt;span class="keyword-directive"&gt;new&lt;/span&gt; RandomNumberGenerator;&lt;br /&gt;       instance-&amp;gt;init();&lt;br /&gt;}&lt;br /&gt;&lt;span class="keyword-directive"&gt;return&lt;/span&gt; instance;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;RandomNumberGenerator::RandomNumberGenerator(){}&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;void&lt;/span&gt; RandomNumberGenerator::init() {&lt;br /&gt;a = time(NULL);&lt;br /&gt;b = time(NULL);&lt;br /&gt;c = time(NULL);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;double&lt;/span&gt; RandomNumberGenerator::getFromUniformDistribution(){&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;static&lt;/span&gt; &lt;span class="keyword-directive"&gt;int&lt;/span&gt; n;&lt;br /&gt;&lt;span class="keyword-directive"&gt;static&lt;/span&gt; &lt;span class="keyword-directive"&gt;double&lt;/span&gt; d,x;&lt;br /&gt;&lt;br /&gt;d = (a + b + c) * 8192;&lt;br /&gt;x = fmod (d,4294967291.0);&lt;br /&gt;a = b; b = c; c= x;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;if&lt;/span&gt; (x &amp;lt; (&lt;span class="keyword-directive"&gt;float&lt;/span&gt;) 2147483648.0) {&lt;br /&gt;       n = (&lt;span class="keyword-directive"&gt;int&lt;/span&gt;) x;&lt;br /&gt;} &lt;span class="keyword-directive"&gt;else&lt;/span&gt; {&lt;br /&gt;       n = (&lt;span class="keyword-directive"&gt;int&lt;/span&gt;) (x - 4294967296.0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword-directive"&gt;return&lt;/span&gt; (n * 2.3283064365e-10 + 0.5);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;CDN...&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[1] &lt;a href="http://pl.wikipedia.org/wiki/Generator_liczb_pseudolosowych"&gt;http://pl.wikipedia.org/wiki/Generator_liczb_pseudolosowych&lt;/a&gt;&lt;br /&gt;[2] &lt;a href="http://www.wnt.pl/product.php?action=0&amp;amp;prod_id=90&amp;amp;hot=1"&gt;"Komputerowe generatory liczb losowych" R. Wieczorkowski R Zieliński, WNT 1997&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3797225076051014298-6144051364142146179?l=devzine.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/14TNOLxpaPGxqbL36uv9lq5Kd4M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/14TNOLxpaPGxqbL36uv9lq5Kd4M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/14TNOLxpaPGxqbL36uv9lq5Kd4M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/14TNOLxpaPGxqbL36uv9lq5Kd4M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Devzine09Alpha/~4/60JgEXeiFm8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://devzine.blogspot.com/feeds/6144051364142146179/comments/default" title="Komentarze do posta" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3797225076051014298&amp;postID=6144051364142146179" title="Komentarze (2)" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/6144051364142146179?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3797225076051014298/posts/default/6144051364142146179?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Devzine09Alpha/~3/60JgEXeiFm8/generator-liczb-pseudolosowych.html" title="Generator liczb pseudolosowych (cz.1)" /><author><name>Paweł Mandes</name><uri>http://www.blogger.com/profile/15323373746228558489</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_k6vqKQCQSW0/S2_nNokptMI/AAAAAAAAAKI/KcZnh5BuFBI/S220/pm.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://devzine.blogspot.com/2009/03/generator-liczb-pseudolosowych.html</feedburner:origLink></entry></feed>

