<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>GAIBlog &#187; delphi</title>
	<atom:link href="http://pebbie.wordpress.com/category/programming/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://pebbie.wordpress.com</link>
	<description>weblog Grafika dan Intelejensia Buatan (GAIB)</description>
	<lastBuildDate>Sun, 01 Nov 2009 16:15:48 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>id</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='pebbie.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/5b4a1b01c2abacd36afb4a5c6575a479?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>GAIBlog &#187; delphi</title>
		<link>http://pebbie.wordpress.com</link>
	</image>
			<item>
		<title>Convex Hull 2D</title>
		<link>http://pebbie.wordpress.com/2009/09/29/convex-hull-2d/</link>
		<comments>http://pebbie.wordpress.com/2009/09/29/convex-hull-2d/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 16:02:29 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[computational geometry]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=352</guid>
		<description><![CDATA[Convex Hull merupakan persoalan klasik dalam geometri komputasional. Persoalan ini saya ketahui pertama kali ketika lomba pemrograman waktu SMA. Persoalannya digambarkan secara sederhana dalam ruang dimensi dua (bidang) sebagai mencari subset dari himpunan titik pada bidang tersebut sedemikian rupa sehingga jika titik-titik tersebut dijadikan poligon maka akan membentuk poligon yang konveks. Suatu poligon dikatakan konveks [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=352&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify"><em>Convex Hull</em> merupakan persoalan klasik dalam geometri komputasional. Persoalan ini saya ketahui pertama kali ketika lomba pemrograman waktu SMA. Persoalannya digambarkan secara sederhana dalam ruang dimensi dua (bidang) sebagai mencari subset dari himpunan titik pada bidang tersebut sedemikian rupa sehingga jika titik-titik tersebut dijadikan poligon maka akan membentuk poligon yang konveks. Suatu poligon dikatakan konveks jika digambarkan garis yang menghubungkan antar titik maka tidak ada garis yang memotong garis yang menjadi batas luar poligon. Definisi lain dari convex hull adalah poligon yang disusun dari subset titik sedemikian sehingga tidak ada titik dari himpunan awal yang berada di luar poligon tersebut (semua titik berada di batas luar atau di dalam area yang dilingkupi oleh poligon tersebut).</p>
<div id="attachment_353" class="wp-caption alignnone" style="width: 386px"><img src="http://pebbie.files.wordpress.com/2009/09/chull.png?w=376&#038;h=310" alt="convex hull" title="convex hull" width="376" height="310" class="size-full wp-image-353" /><p class="wp-caption-text">convex hull</p></div>
<p><span id="more-352"></span></p>
<p align="justify">Petunjuk untuk menyelesaikan persoalan ini adalah persamaan garis pada bidang. Persamaan garis pada bidang memisahkan bidang menjadi dua bagian yaitu area di sebelah kanan bidang (relatif terhadap orientasi garis). Sebagai contoh garis berorientasi adalah sumbu koordinat. Misalkan saja sumbu vertikal (ordinat, arah orientasi ke atas), seluruh titik di sebelah kanan garis ini memiliki nilai komponen koordinat horizontal (X) yang positif sedangkan seluruh titik di sebelah kiri garis memiliki nilai komponen koordinat horizontal negatif.</p>
<p align="justify">Petunjuk di atas dimanfaatkan dengan membuat definisi bahwa garis yang dibentuk oleh titik-titik poligon jika diasumsikan memiliki orientasi yang sama, maka setiap titik berada di sebelah kanan seluruh garis batas tersebut. Definisi ini kemudian dimanfaatkan untuk menentukan aksi awal yaitu memilih titik yang berada paling luar pertama. Mencari titik pertama cukup mudah yaitu cukup memilih titik yang memiliki nilai komponen koordinat (horizontal atau vertikal) yang ekstrim (minimum atau maksimum). Titik-titik convex hull lainnya ditentukan berdasarkan titik pertama tadi.</p>
<p>Algoritma awal yang intuitif dari deskripsi paragraf sebelumnya adalah.<br />
<code></p>
<ol>
<li>memilih titik pertama</li>
<li>memilih titik berikutnya, berdasarkan definisi:
<ul>
<li>jika dibuat garis dengan titik sebelumnya maka seluruh titik lainnya tidak ada yang berada di sebelah kiri.</li>
<li>jika titik tersebut sesuai maka dimasukkan dalam daftar titik luar.</li>
</ul>
</li>
</ol>
<p></code></p>
<p align="justify">Algoritma tersebut menggunakan pendekatan exhaustive (brute-force). kompleksitas algoritma tersebut mendekati <strong>O</strong>(n<sup>2</sup>). Algoritma tersebut dapat dioptimasi dengan membuat agar kumpulan titik-titik tersebut terurut secara lexicografis (urutkan dulu berdasarkan koordinat sumbu-X lalu untuk koordinat pada sumbu-X yang sama urutkan berdasarkan koordinat pada sumbu-Y). Sifat keterurutan ini kemudian dimanfaatkan sehingga pada setiap fase tiap titik hanya dikunjungi satu kali (kompleksitas linier). Adapun fase-fase yang perlu dilalui terdiri dari dua fase yaitu batas bagian atas (<em>upper boundary</em>) dan batas bagian bawah (<em>lower boundary</em>). Misal pada contoh algoritma berikut :</p>
<pre class="brush: delphi;">
procedure TForm1.ConvexHull( ap: array of TPoint );
var

  pi                : array of integer;
  hull              : array of integer;
  h, i, j, k, l     : integer;
  dx, dy, dx2, dy2  : integer;
  found             : boolean;
begin
  { initialize index }
  setlength( pi, length( ap ) );
  for i := 0 to high( pi ) do
    pi[i] := i;

  { sort the index lexicographically, shown here using simple quadratic complexity sort algorithm }
  for i := 0 to high( pi ) - 1 do begin
    for j := i + 1 to high( pi ) do begin
      if ( ap[pi[j]].X &lt; ap[pi[i]].X ) or ( ( ap[pi[j]].X &lt; ap[pi[i]].X ) and ( ap[pi[j]].Y &gt; ap[pi[i]].Y ) ) then begin
        k := pi[j];
        pi[j] := pi[i];
        pi[i] := k;
      end;
    end;
  end;

  { build upper boundary }
  setlength( hull, 2 );
  hull[0] := pi[0];
  hull[1] := pi[1];
  h := 1;

  for i := 2 to high( pi ) do begin
    found := false;
    for k := 1 to high( hull ) do begin
      dx := ap[hull[k]].X - ap[hull[k - 1]].X;
      dy := ap[hull[k]].Y - ap[hull[k - 1]].Y;

      dx2 := ap[pi[i]].X - ap[hull[k]].X;
      dy2 := ap[pi[i]].Y - ap[hull[k]].Y;

      j := dy * dx2 - dx * dy2;
      { delete previous non-convex edge w.r.t current point }
      if j &gt; 0 then begin
        hull[k] := pi[i];
        setlength( hull, k + 1 );
        found := true;
        break;
      end;
    end;

    { add if current point lies on the right side of previous upper edges }
    if not found then begin
      setlength( hull, length( hull ) + 1 );
      hull[high( hull )] := pi[i];
    end;
  end; 

  { build lower boundary }
  h := high( hull ) - 1;
  for i := high( pi ) downto 0 do begin
    found := false;
    for k := h to high( hull ) do begin
      dx := ap[hull[k]].X - ap[hull[k - 1]].X;
      dy := ap[hull[k]].Y - ap[hull[k - 1]].Y;

      dx2 := ap[pi[i]].X - ap[hull[k]].X;
      dy2 := ap[pi[i]].Y - ap[hull[k]].Y;

      j := dy * dx2 - dx * dy2;
      if j &gt; 0 then begin
        hull[k] := pi[i];
        setlength( hull, k + 1 );
        found := true;
        break;
      end;
    end;

    if not found then begin
      setlength( hull, length( hull ) + 1 );
      hull[high( hull )] := pi[i];
    end;
  end;

  { display result }
  Image1.Canvas.Pen.Color := clLime;
  Image1.Canvas.MoveTo( ap[hull[0]].X, ap[hull[0]].Y );
  for i := 1 to high( hull ) do
    Image1.Canvas.LineTo( ap[hull[i]].X, ap[hull[i]].Y );
  for i := 0 to high( hull ) do
    drawpt( ap[hull[i]].X, ap[hull[i]].Y, clRed );

end;
</pre>
<p align="justify">Algoritma di atas terdiri dari tiga bagian yaitu pengurutan titik, penyusunan batas bagian atas, dan penyusunan batas bagian bawah. Pada contoh di atas kompleksitas ditentukan oleh algoritma pengurutan titik yang cenderung kuadratik (<strong>O</strong>(n<sup>2</sup>)) untuk mempermudah pemahaman, jika dibutuhkan algoritma pengurutan dapat menggunakan algoritma yang memiliki kompleksitas lebih rendah/linearitmik (<strong>O</strong>(n.<strong>log</strong> n)).</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/352/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=352&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2009/09/29/convex-hull-2d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2009/09/chull.png" medium="image">
			<media:title type="html">convex hull</media:title>
		</media:content>
	</item>
		<item>
		<title>Programmatically set core affinity in multicore environment</title>
		<link>http://pebbie.wordpress.com/2009/06/02/programmatically-set-core-affinity-in-multicore-environment/</link>
		<comments>http://pebbie.wordpress.com/2009/06/02/programmatically-set-core-affinity-in-multicore-environment/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 07:48:36 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[core affinity]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=320</guid>
		<description><![CDATA[Prosesor multicore sudah tidak asing tetapi aplikasi yang umumnya dikembangkan biasanya hanya terdiri dari satu thread. Sejak dahulu ternyata sudah ada Win32 API untuk menentukan afinitas proses/thread ke prosesor tertentu. Kode di bawah menggunakan delphi 7.
Mendapatkan Jumlah core/Prosesor
var
  sinfo : TSystemInfo;
begin
  GetSystemInfo(sinfo);
  { jumlah prosesor ada di field dwNumberOfProcessors }
  showmessage(inttostr(sinfo.dwNumberOfProcessors));

Menentukan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=320&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Prosesor multicore sudah tidak asing tetapi aplikasi yang umumnya dikembangkan biasanya hanya terdiri dari satu thread. Sejak dahulu ternyata sudah ada Win32 API untuk menentukan afinitas proses/thread ke prosesor tertentu. Kode di bawah menggunakan delphi 7.</p>
<p><strong>Mendapatkan Jumlah core/Prosesor</strong></p>
<pre class="brush: delphi;">var
  sinfo : TSystemInfo;
begin
  GetSystemInfo(sinfo);
  { jumlah prosesor ada di field dwNumberOfProcessors }
  showmessage(inttostr(sinfo.dwNumberOfProcessors));
</pre>
<p><strong>Menentukan Afinitas ke core tertentu</strong><br />
Afinitas ke core menggunakan bit vector. Tiap 1 bit diasosiasikan ke core tertentu mulai dari LSB. karena tipe data yang dilemparkan ke fungsi tsb adalah 32 bit unsigned integer maka mungkin maksimum prosesor yang bisa diakses sejumlah 32.</p>
<p>berikut ini contoh kode agar aplikasi yang sedang berjalan hanya menggunakan core pertama (cpu0) saja.</p>
<pre class="brush: delphi;">SetProcessAffinityMask(GetCurrentProcess, 1);</pre>
<p>berikut ini contoh kode agar aplikasi yang sedang berjalan hanya menggunakan core pertama (cpu0) dan kedua (cpu1).</p>
<pre class="brush: delphi;">SetProcessAffinityMask(GetCurrentProcess, 3);</pre>
<p>sedangkan berikut ini contoh kode agar aplikasi yang sedang berjalan hanya menggunakan core kedua (cpu0) saja.</p>
<pre class="brush: delphi;">SetProcessAffinityMask(GetCurrentProcess, 2);</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/320/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=320&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2009/06/02/programmatically-set-core-affinity-in-multicore-environment/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>On Base64</title>
		<link>http://pebbie.wordpress.com/2009/03/31/on-base64/</link>
		<comments>http://pebbie.wordpress.com/2009/03/31/on-base64/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 16:47:00 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[base64]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=273</guid>
		<description><![CDATA[*duh, dah lama nggak update blog saking sibuknya (cari alesan)*
Beberapa waktu yang lalu ada permintaan untuk melakukan encoding/decoding ke format base64. karena waktu yang mendesak dan jumlah item requirement yang banyak maka alternatif pertama adalah mencari kode public domain di internet. ternyata tidak satupun yang bisa dipakai (pada saat yang sempit itu). hambatannya bermacam-macam, mulai [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=273&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>*duh, dah lama nggak update blog saking sibuknya (cari alesan)*</p>
<p>Beberapa waktu yang lalu ada permintaan untuk melakukan <em>encoding/decoding</em> ke format <a href="http://en.wikipedia.org/wiki/Base64">base64</a>. karena waktu yang mendesak dan jumlah <em>item requirement</em> yang banyak maka alternatif pertama adalah mencari kode <em>public domain</em> di internet. ternyata tidak satupun yang bisa dipakai (pada saat yang sempit itu). hambatannya bermacam-macam, mulai dari hasil <em>encoding</em> yang tidak sesuai, atau hasil <em>decoding</em> yang beda dengan acuan. setelah duduk sebentar sambil <em>melototin</em> lagi halaman wikipedia yang mendeskripsikan aturan pengkodean basis64 akhirnya langkah terakhir malah bikin sendiri fungsi yang sesuai dengan spek (teks dari/ke base64, <em>binary</em>(variabel bertipe ataupun <em>byte stream</em>) dari/ke base64).</p>
<p>bagi yang berminat menggunakan, dipersilakan menggunakan kode berikut sebebas-bebasnya (pubdom as no warranty for using).<br />
<span id="more-273"></span></p>
<pre class="brush: delphi;">(*
 * auth : Peb Ruswono Aryan
 * desc : base64 encoding/decoding for delphi
 *)
type
  tbytearr = array of byte;

{
	encode64 : Pointer x Nat --&gt; string
	desc: encode binary data to base64 message
}
function encode64( const v: Pointer; vsize: cardinal ): string;
const
  lut64             = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var
  tribyte           : array[0..2] of byte;
  p                 : PByteArray;
  ci, i             : cardinal;

  function enc3byteto4char( len: integer ): string;
  begin
    result := lut64[1 + tribyte[0] shr 2];
    result := result + lut64[1 + ( ( tribyte[0] and $03 ) shl 4 ) + ( tribyte[1] shr 4 )];
    if len &gt; 1 then
      result := result + lut64[1 + ( tribyte[1] and $0F ) shl 2 + ( tribyte[2] shr 6 )]
    else
      result := result + '=';
    if len &gt; 2 then
      result := result + lut64[1 + tribyte[2] and $3F]
    else
      result := result + '=';
  end;
begin
  p := PByteArray( v );
  ci := 0;
  repeat
    i := 0;
    while i &lt; 3 do begin
      if ci &gt;= vsize then break;
      tribyte[i] := p[ci];
      inc( ci );
      inc( i );
    end;
    result := result + enc3byteto4char( i );
  until ci &gt;= vsize;
end;

{
	decode64 : String --&gt; DynamicArray of byte
	desc: decode base64message to binary data (array of byte)
}
function decode64( msg: string ): TbyteArr;
var
  pb                : array of byte;
  lm, pi            : integer;
  len               : integer;

  function decodechar( c: char; var code: byte ): boolean;
  begin
    result := true;
    case c of
      'A'..'Z': code := ord( c ) - ord( 'A' );
      'a'..'z': code := ord( c ) - ord( 'a' ) + 26;
      '0'..'9': code := ord( c ) - ord( '0' ) + 52;
      '+': code := 62;
      '/': code := 63;
    else
      result := false;
    end;
  end;

  procedure decodeblock( blk: string );
  var
    t, i            : byte;
    w               : dword;
  begin
    w := 0;
    i := 0;
    while i &lt; 4 do begin
      if not decodechar( blk[i + 1], t ) then break;
      w := w shl 6 + t;
      inc( i );
    end;
    result[pi] := ( w shr 16 ) and $FF;
    inc( pi );
    if pi &gt;= len then exit;
    result[pi] := ( w shr 8 ) and $FF;
    inc( pi );
    if pi &gt;= len then exit;
    result[pi] := ( w and $FF );
    inc( pi );
  end;
begin
  len := length( msg ) * 3 div 4;
  lm := length( msg );
  if msg[lm] = '=' then dec( len );
  if msg[lm - 1] = '=' then dec( len );
  setlength( result, len );
  pi := 0;
  repeat
    decodeblock( copy( msg, 1, 4 ) );
    delete( msg, 1, 4 );
  until length( msg ) &lt;= 0;
end;

{
	encode64str : string --&gt; string
	desc: encode text string into base64 message
}
function encode64str( msg: string ): string;
var
  p                 : TByteArr;
  i                 : integer;
begin
  setlength( p, length( msg ) );
  for i := 0 to high( p ) do
    p[i] := ord( msg[i + 1] );
  result := encode64( @p[0], length( p ) );
end;

{
	decode64str : string --&gt; string
	desc: decode base64 message containing text
}
function decode64str( msg: string ): string;
var
  p                 : TByteArr;
  i                 : integer;
begin
  result := '';
  p := decode64( msg );
  for i := 0 to length( p ) do
    result := result + chr( p[i] );
end;</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/273/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/273/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/273/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=273&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2009/03/31/on-base64/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Do it yourself CCTV/Surveilance from scratch</title>
		<link>http://pebbie.wordpress.com/2009/01/18/do-it-yourself-cctvsurveilance-from-scratch/</link>
		<comments>http://pebbie.wordpress.com/2009/01/18/do-it-yourself-cctvsurveilance-from-scratch/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 17:47:53 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[cctv]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[webcam]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=257</guid>
		<description><![CDATA[Terinspirasi dengan tulisan tentang memasang sendiri sistem cctv dengan zoneminder saya jadi iseng membuat sistem serupa (bukan memasang lagi, ini membuat). Awalnya memang tidak berniat untuk ke arah sana, hanya ingin melakukan interpretasi citra dengan memanfaatkan webcam, tapi kemudian terhambat karena framerate yang lambat ketika awal-awal mencoba.

Pendahuluan
Oke, mari dimulai percobaannya. Spesifikasi kita kali ini adalah [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=257&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify">Terinspirasi dengan tulisan tentang <a href="http://ryosaeba.wordpress.com/2009/01/18/diy-cctv-dengan-zoneminder/">memasang sendiri sistem cctv dengan zoneminder</a> saya jadi iseng membuat sistem serupa (bukan memasang lagi, ini membuat). Awalnya memang tidak berniat untuk ke arah sana, hanya ingin melakukan interpretasi citra dengan memanfaatkan webcam, tapi kemudian terhambat karena <em>framerate</em> yang lambat ketika awal-awal mencoba.</p>
<p><span id="more-257"></span><br />
<strong>Pendahuluan</strong></p>
<p align="justify">Oke, mari dimulai percobaannya. Spesifikasi kita kali ini adalah membuat sistem cctv yang mengambil gambar dari webcam dan dapat diakses melalui web server (ujung yang cukup generik, bisa diperluas dengan membuat mobile client yang mengakses http <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ). Selain itu tiap gambar diarsipkan sehingga memungkinkan untuk pemrosesan yang tidak membutuhkan tenggat. Agar lebih sederhana, kita akan mendekomposisi sistem yang kita buat menjadi 3 modul : </p>
<ol>
<li>program pengakses webcam (GUI). </li>
<li>program perantara (CLI, bisa jadi opsional, nanti akan dijelaskan alasannya).</li>
<li>halaman web (HTML+PHP)</li>
</ol>
<p><strong>Alat dan Bahan</strong><br />
Berikutnya alat yang diperlukan : </p>
<ul>
<li>web server (saya menggunakan xampp 1.5). modul yang diperlukan sebetulnya hanya apache dan php. database tidak diperlukan saat ini untuk menyederhanakan program.</li>
<li>compiler delphi (anda bisa menggunakan apapun sebetulnya, tapi saya menggunakan delphi)</li>
<li><em>A win32 machine</em>. ya ya.. saya pakai API Windows tapi nggak pakai DirectX, cuma pakai VFW (Video for Windows). stok lama.</li>
<li>Webcam. USB atau apapun. sekali-lagi, demi kesederhanaan, saya hanya menggunakan 1 webcam (default) yang ada di laptop. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </li>
</ul>
<p><strong>Arsitektur sistem</strong><br />
gambaran umum sistem bisa dilihat dalam gambar berikut.<br />
<img src="http://pebbie.files.wordpress.com/2009/01/cctv.png?w=410&#038;h=302" alt="arsitektur cctv (7KB)" title="arsitektur cctv" width="410" height="302" class="alignnone size-full wp-image-258" /><br />
Program 1,2, dan 3 sesuai dengan penjelasan di awal.</p>
<p><strong>Program 1</strong></p>
<p align="justify">Program ini dibuat menggunakan delphi dan terdiri dari 1 modul webcam dan 1 form. berikut ini kode untuk unit pengakses webcam (konstanta dan prosedur sudah di-dietkan supaya hanya mengandung yang diperlukan saja). </p>
<pre class="brush: delphi;">unit _cam;

interface

uses
  Windows,
  Messages,
  Controls,
  ExtCtrls;

const
  WM_CAP_START      = WM_USER;
  WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
  WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
  WM_CAP_SAVEDIB    = WM_CAP_START + 25;
  WM_CAP_COPY       = WM_CAP_START + 30;
  WM_CAP_SET_SCALE  = WM_CAP_START + 53;
  WM_CAP_SET_PREVIEW = ( WM_CAP_START + 50 );
  WM_CAP_SET_OVERLAY = ( WM_CAP_START + 51 );
  WM_CAP_SET_PREVIEWRATE = ( WM_CAP_START + 52 );

type
  TCam = class
  protected
    hWndC: HWND;
    FIsCapturing: Boolean;
    procedure BeginCapture( Container: TWinControl );
    procedure EndCapture;
  public
  	constructor Create( Container: TWinControl );
    destructor Free;
  	property Handle:HWND read hwndc;
  	property Capturing:boolean read FIsCapturing;
    procedure CopyToClipboard;
    procedure SaveToFile( filename: string );
  end;

implementation

uses
  ClipBrd;

function capCreateCaptureWindowA( lpszWindowName: PCHAR;
  dwStyle: longint;
  x: integer;
  y: integer;
  nWidth: integer;
  nHeight: integer;
  ParentWin: HWND;
  nId: integer ): HWND; stdcall external
'AVICAP32.DLL';

{ TCam }

procedure TCam.BeginCapture( Container: TWinControl );
begin
  hWndC := capCreateCaptureWindowA( 'Capture Window',
    WS_CHILD or WS_VISIBLE,
    Container.Left,
    Container.Top,
    Container.Width,
    Container.Height,
    Container.Handle,
    0 );
  if hWndC &lt;&gt; 0 then begin
    SendMessage( hWndC, WM_CAP_DRIVER_CONNECT, 0, 0 );
    SendMessage( hWndC, WM_CAP_SET_SCALE, 1, 0 );
    SendMessage( hWndC, WM_CAP_SET_PREVIEWRATE, 24, 0 );
    SendMessage( hWndC, WM_CAP_SET_PREVIEW, 1, 0 );
    FIsCapturing := True;
  end;
end;

procedure TCam.CopyToClipboard;
begin
	if hWndC &lt;&gt; 0 then begin
    SendMessage( hwndc, WM_CAP_COPY, 0, 0 );
  end;
end;

procedure TCam.EndCapture;
begin
	FIsCapturing := False;
	if hWndC &lt;&gt; 0 then begin
    SendMessage( hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0 );
    hWndC := 0;
  end;
end;

procedure TCam.SaveToFile( filename: string );
begin
  if hWndC &lt;&gt; 0 then begin
    SendMessage( hWndC,
      WM_CAP_SAVEDIB,
      0,
      longint( pchar( filename ) )
      );
  end;
end;

constructor TCam.Create(Container: TWinControl);
begin
	inherited Create;
	BeginCapture(Container);
end;

destructor TCam.Free;
begin
	EndCapture;
end;

end.</pre>
<p>sedangkan kode untuk formnya adalah sebagai berikut. satu hal yang perlu diperhatikan. form berikut saya buat StayOnTop karena kalau di-minimize atau tersembunyi, gambarnya tidak akan di-<em>update</em>. Hal lainnya adalah pengaturan webcam agar bisa didapat framerate yang tinggi (di laptop saya setelah beberapa fitur dimatikan seperti low-light boost dan color boost baru bisa berjalan di 25 FPS).</p>
<pre class="brush: vb;">//unit1.dfm
object Form1: TForm1
  Left = 192
  Top = 107
  BorderStyle = bsDialog
  Caption = 'Form1'
  ClientHeight = 241
  ClientWidth = 321
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsStayOnTop
  OldCreateOrder = False
  OnCloseQuery = FormCloseQuery
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 320
    Height = 240
    BevelOuter = bvNone
    Color = clBlack
    TabOrder = 0
  end
  object _proc: TTimer
    Enabled = False
    Interval = 48
    OnTimer = _procTimer
    Left = 56
    Top = 16
  end
end</pre>
<p>dan <em>code-behind</em>-nya adalah sebagai berikut.</p>
<pre class="brush: delphi;">unit Unit1;

interface
uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  ExtCtrls,
  MPlayer,
  StdCtrls,
  citra,
  Spin,
  ClipBrd,
  _cam,
  jpeg,
  inifiles;

type
  TForm1 = class( TForm )
    Panel1: TPanel;
    _proc: TTimer;
    procedure FormCreate( Sender: TObject );
    procedure FormCloseQuery( Sender: TObject; var CanClose: Boolean );
    procedure _procTimer( Sender: TObject );
  private
    cam: TCam;
    bmp: TBitmap;
    jpg: TJpegImage;
    ini: TIniFile;
  public
  end;

var
  Form1             : TForm1;
  capmode           : integer;
  datapath          : string;

implementation
{$R *.DFM}

{ TForm1 }

procedure TForm1.FormCreate( Sender: TObject );
begin
  ini := TIniFile.Create( extractfilepath( application.ExeName ) + 'config.ini' );
  capmode := ini.ReadInteger( 'server', 'mode', 0 );
  if capmode = 2 then begin
    datapath := ini.ReadString( 'server', 'datadir', 'data' );
    if pos( ':', datapath ) = 0 then datapath := extractfilepath( application.ExeName ) + datapath;
  end;
  jpg := TJpegImage.Create;
  jpg.CompressionQuality := ini.ReadInteger('server','jpegquality', 40);
  _proc.Interval := 1000 div ini.ReadInteger('server', 'fps', 5);
  bmp := TBitmap.Create;
  if not Assigned( cam ) then cam := TCam.Create( Panel1 );
  _proc.Enabled := cam.Capturing;
end;

procedure TForm1.FormCloseQuery( Sender: TObject; var CanClose: Boolean );
begin
  CanClose := False;
  _proc.Enabled := false;
  jpg.Free;
  bmp.Free;
  if Assigned( cam ) then cam.Free;
  CanClose := True;
end;

procedure TForm1._procTimer( Sender: TObject );
begin
  if cam.Capturing then begin
    if capmode &gt; 0 then begin
      cam.CopyToClipboard;
      if capmode = 2 then begin
        bmp.Assign( clipboard );
        jpg.Assign( bmp );
        jpg.SaveToFile( format( '%s\%.12d.jpg', [datapath, gettickcount] ) );
      end;
    end;
  end;
end;

end.</pre>
<p align="justify">Program di atas akan menyimpan hasil rekaman dari webcam ke dalam file dalam format JPEG yang kualitasnya dapat diparameterkan sehingga ukuran file keluarannya dapat juga diatur. Nama file rekaman menggunakan gettickcount yang dikodekan menjadi string sepanjang 12 digit. Penggunaan angkan dimaksudkan agar memudahkan dalam mencari file terakhir tanpa harus menggunakan database. Untuk sementara semua hasil rekaman dari webcam disimpan dalam satu direktori (datadir). Selanjutnya bisa menggunakan struktur direktori yang mencerminkan tanggal (YYYY\MM\DD\) untuk memudahkan pengarsipan.<br />
program di atas menggunakan file konfigurasi dengan nama config.ini yang lokasinya sama dengan lokasi executable.</p>
<p>[server]<br />
#mode capture<br />
#0:no save<br />
#1:save to clipboard<br />
#2:save to file (jpeg)<br />
mode=2<br />
datadir=data<br />
jpegquality=40<br />
fps=10</p>
<p>konfigurasi di atas akan membuat program webcam menyimpan 10 gambar tiap detik dengan kualitas kompresi sekitar 40 (untuk resolusi webcam 320&#215;240 membutuhkan sekitar 5KB). Dari hasil hitung-hitungan. kalau 1 detik 10 gambar dikali 5 KB jadi 50. satu jam perlu 180MB. satu hari perlu 4GB. sedangkan 1 tahun perlu ~1.5TB. angka-angka tersebut adalah gambaran kasar dengan asumsi tiap detik direkam (biarpun tidak ada perubahan). untuk analisis lebih lanjut (membuat gambar-gambar yang tidak berubah) bisa dilakukan dengan membuat program lain yang bekerja pada direktori tersebut ^_^. </p>
<p><strong>Web Interface</strong></p>
<p>Berikutnya adalah program nomor 3 yaitu halaman web yang terdiri dari dua file yaitu index.html dan getimg.php.</p>
<pre class="brush: xml;">&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;refresh&quot; content=&quot;3&quot; /&gt;
	&lt;/head&gt;
	&lt;body&gt;
	&lt;img src=&quot;getimg.php&quot;/&gt;&lt;/body&gt;
&lt;/html&gt;</pre>
<pre class="brush: php;">&lt;?php
//file: getimg.php
$t = time().'.txt';
$result = system('cctv &quot;C:\Program Files\Borland\Delphi7\Projects\cctv\data&quot; &gt; '.$t);
if (file_exists($t)){
	$result = file_get_contents($t);
	$img = urldecode(str_replace('%0D%0A', '', urlencode($result)));
	header('Content-type:image');
	echo file_get_contents($img);
	unlink($t);
}
?&gt;</pre>
<p><strong>Perantara</strong></p>
<p align="justify">Yang terakhir adalah program perantara. Ada alasan khusus mengapa saya membuat program perantara dibanding menjadikannya langsung dalam skrip PHP yaitu yang pertama terpikir. hehehe.. persoalannya adalah mengambil file terakhir (timestamp terbesar) dalam direktori yang membutuhkan iterasi ke tiap file (silakan coba buat versi skrip php-nya dan bandingkan dengan versi pemanggilan command-line).</p>
<pre class="brush: delphi;">program cctv;
{$APPTYPE CONSOLE}

uses
  SysUtils;

var
	tdir : string;

procedure pandu;
begin
  writeln( 'ERR: use cctv &lt;datadir&gt;' );
end;

function getlastfile( dir: string ): string;
var
  sr                : TSearchRec;
  FileAttrs         : integer;
  tmp               : string;
  mask              : string;
  cur, last         : longint;
begin
  result := '';
  last := -1;
  mask := '*.*';
  FileAttrs := faAnyFile or faDirectory;
  if FindFirst( dir + '\' + mask, FileAttrs, sr ) = 0 then begin
    repeat
      if ( Pos( '.', sr.Name ) &lt;&gt; 1 ) then begin
        tmp := dir + '\' + sr.Name;
        trystrtoint( changefileext( sr.Name, '' ), cur );
        if cur &gt; last then begin
          result := tmp;
          last := cur;
        end;
      end;
    until FindNext( sr ) &lt;&gt; 0;
    FindClose( sr );
  end;
end;

begin
  if ParamCount &lt; 1 then pandu;
  tdir := getlastfile( paramstr( 1 ) );
  if tdir &lt;&gt; '' then writeln( tdir );
end.</pre>
<p><strong>Penutup</strong><br />
Akhirnya selesai juga. pesan terakhir dari saya, tidak ada skinsyut hasil program karena subjek yang dijadikan skrinsyutnya (saya) sudah kusut <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> . silakan dicoba sendiri, kalau ada yang nggak berhasil silakan komentar di sini (belum tentu saya bantu juga sih <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ).</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/257/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=257&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2009/01/18/do-it-yourself-cctvsurveilance-from-scratch/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2009/01/cctv.png" medium="image">
			<media:title type="html">arsitektur cctv</media:title>
		</media:content>
	</item>
		<item>
		<title>Faster Logarithm Function</title>
		<link>http://pebbie.wordpress.com/2009/01/07/faster-logarithm-function/</link>
		<comments>http://pebbie.wordpress.com/2009/01/07/faster-logarithm-function/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 14:36:15 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[log function]]></category>
		<category><![CDATA[lut]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[sse]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=248</guid>
		<description><![CDATA[Fungsi logaritma merupakan fungsi yang termasuk lambat, bahkan dibanding dengan trigonometri (CMIIW). Beberapa waktu yang lalu yang terjebak dalam persoalan yang seringkali memanggil fungsi logaritma khususnya log10 untuk setiap iterasi. walaupun sudah mengurangi pemanggilan dengan memanfaatkan variabel, namun tetap saja program berjalan lambat. Akhirnya setelah bertanya dan mencari-cari, ada[1] yang membuat implementasi fungsi logaritma yang [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=248&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify">Fungsi logaritma merupakan fungsi yang termasuk lambat, bahkan dibanding dengan trigonometri (CMIIW). Beberapa waktu yang lalu yang terjebak dalam persoalan yang seringkali memanggil fungsi logaritma khususnya log10 untuk setiap iterasi. walaupun sudah mengurangi pemanggilan dengan memanfaatkan variabel, namun tetap saja program berjalan lambat. Akhirnya setelah <a href="http://www.gamedevid.org/forum/showthread.php?t=7082">bertanya</a> dan mencari-cari, ada[1] yang membuat implementasi fungsi logaritma yang lebih cepat dan tetap dalam batas error yang bisa diterima (1e-6). Idenya adalah membuat look-up table dari bit mantissa yang sudah dikuantisasi (di kliping) sehingga ukuran LUT-nya cukup kecil (implementasi yang saya buat hanya berukuran 256K) yang menurut penulis aslinya cukup untuk disimpan di dalam cache CPU.</p>
<p><span id="more-248"></span></p>
<p align="justify">Dari contoh kode yang dilampirkan di paper[1] dalam bahasa C dan untuk fungsi logaritma natural (ln), saya ubah sesuai dengan kebutuhan saya yaitu log10 dan dalam bahasa pascal (delphi)</p>
<pre class="brush: delphi;">
var
 {16 bit used for mantissa lookup}
  lut               : array[0..65535] of single;
{IEEE 754 32-bit Floating-Point Number}

procedure precalc_lut;
var
  step              : integer;
  i, p, x           : integer;
  fval              : single;
  pf                : ^dword;

begin
  pf := @fval;
  x := $3F800000;
  pf^ := x;
  step := 1 shl 16;//23 - 7
  p := 1 shl 7;
  for i := 0 to p - 1 do begin
    lut[i] := log2( fval );
    x := x + step;
    pf^ := x;
  end;
end;

function _log10( val: single ): single; register;
var
  pf                : ^dword;
  x, log_2        : integer;
begin
  pf := @val;
  x := pf^;
  log_2 := ( ( x shr 23 ) and $FF ) - 127;
  x := (x and $7FFFFF) shr 16;
  result := (
  ( lut[x]
  + log_2
  )
  * 0.301029995664
  );
end;</pre>
<p>hasilnya setelah diuji coba (1000000 pemanggilan fungsi, menggunakan gettickcount), lumayan ~4 kali lebih cepat dibanding fungsi log10 bawaan delphi (unit Math).</p>
<p>di lain pihak, ternyata <a href="http://www.gamedevid.org/forum/showpost.php?p=86863&amp;postcount=4">Om Kiki pun membuat implementasi menggunakan deret MacLaurin dalam SSE</a>. Walaupun nggak terlalu akurat dan terbatas di interval 0 &lt; x &lt; 2. </p>
<pre class="brush: cpp;">#include &lt;cstdio&gt;
#include &lt;cmath&gt;
#include &lt;xmmintrin.h&gt;

float maclaurin(float val){
        __declspec(align(16) ) float tmp[4] = { 1.0F,1.0F,1.0F,0.0F};
        __declspec(align(16) ) float multiplier[4] = { 1.0F,-0.5F,0.33333333F,-0.25F};
        tmp[3] = val;
        __m128 vec1 = _mm_load_ps(tmp);
        __m128 vec2 = _mm_shuffle_ps( vec1,vec1,0xF4);
        __m128 vec3 = _mm_shuffle_ps( vec1,vec1,0xFC);
        __m128 vec4 = _mm_shuffle_ps( vec1,vec1,0xFF);
        __m128 acc  = _mm_mul_ps(vec1, vec2);
        acc  = _mm_mul_ps(acc, vec3);
        vec1 = _mm_load_ps(multiplier);
        acc  = _mm_mul_ps(acc, vec4);
        acc  = _mm_mul_ps(acc,vec1);
        vec1 = _mm_shuffle_ps(acc,acc, 0xE4);
        vec2 = _mm_shuffle_ps(acc,acc, 0x39);
        vec3 = _mm_shuffle_ps(acc,acc, 0x4E);
        vec4 = _mm_shuffle_ps(acc,acc, 0x93);
        acc  = _mm_add_ps(vec1,vec2);
        acc  = _mm_add_ps( acc, vec3);
        acc  = _mm_add_ps(acc, vec4);
        float res;
        _mm_store_ss(&amp;res,acc);
        return res;
}

float my_log(float x){
        return maclaurin(x - 1);
}

int main(){
        float reference = logf(1.3F);
        float target    = my_log(1.3F);
        printf(&quot; reference = %g , target = %g\n&quot;, reference, target);
}</pre>
<p><strong>Referensi</strong></p>
<ol>
<li>vinyals, Oriol; et al. Revisiting Basic function on current CPUs: A fast logarithm implementation with adjustable accuracy. June 21, 2007. ICSI Berkeley Report</li>
</ol>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/248/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/248/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/248/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/248/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/248/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/248/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/248/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/248/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/248/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/248/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=248&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2009/01/07/faster-logarithm-function/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Algoritma K-means clustering</title>
		<link>http://pebbie.wordpress.com/2008/11/13/algoritma-k-means-clustering/</link>
		<comments>http://pebbie.wordpress.com/2008/11/13/algoritma-k-means-clustering/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 11:35:40 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[clustering]]></category>
		<category><![CDATA[color quantization]]></category>
		<category><![CDATA[k-means]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=234</guid>
		<description><![CDATA[K-Means adalah teknik yang cukup sederhana dan cepat dalam pekerjaan pengelompokkan data (clustering). Prinsip utama dari teknik ini adalah menyusun k buah prototipe/pusat massa (centroid)/rata-rata (mean) dari sekumpulan data berdimensi n. Teknik ini mensyaratkan nilai k sudah diketahui sebelumnya (a priori). Algoritma k-means dimulai dengan pembentukan prototipe cluster di awal kemudian secara iteratif prototipe cluster [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=234&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify"><em>K-Means</em> adalah teknik yang cukup sederhana dan cepat dalam pekerjaan pengelompokkan data (clustering). Prinsip utama dari teknik ini adalah menyusun <strong>k</strong> buah prototipe/pusat massa (<em>centroid</em>)/rata-rata (<em>mean</em>) dari sekumpulan data berdimensi <strong>n</strong>. Teknik ini mensyaratkan nilai <strong>k</strong> sudah diketahui sebelumnya (<em>a priori</em>). Algoritma k-means dimulai dengan pembentukan prototipe cluster di awal kemudian secara iteratif prototipe cluster ini diperbaiki hingga konvergen (tidak terjadi perubahan yang signifikan pada prototipe cluster). Perubahan ini diukur menggunakan fungsi objektif J yang umumnya didefinisikan sebagai jumlah atau rata-rata jarak tiap item data dengan pusat massa kelompoknya. Secara lebih detil algoritma k-means adalah seperti berikut : </p>
<ol>
<li>inisialisasi nilai J (misal MAXINT)</li>
<li>Tentukan prototipe cluster awal (bisa secara acak ataupun dipilih salah satu secara acak dari koleksi data)</li>
<li>Masukkan tiap satuan data ke dalam kelompok yang <em>jarak</em> dengan pusat massa-nya paling dekat</li>
<li>ubah nilai pusat massa tiap cluster sebagai rata-rata (mean) dari seluruh anggota kelompok tersebut</li>
<li>Hitung fungsi objektif <strong>J</strong></li>
<li>jika nilai J sama dengan sebelumnya, berhenti atau ulangi langkah 3</li>
</ol>
<p><span id="more-234"></span><br />
Berikut ini adalah contoh implementasi algoritma k-means dalam delphi.</p>
<pre class="brush: delphi;">{ garis besar kode }
type
  TTrainingData=record
    feature : array of real;
    truth : integer;
  end;

procedure DoKMeans;
begin
  Initialize;
  repeat
    Inc(NumStep);

    ReviseMinimum;
    CalculateCentroid;
    MeasureAccuracy;

  until IsConverge or (NumStep &gt; MaxStep);
end;
</pre>
<pre class="brush: delphi;">
var
  NumStep,MaxStep : longint;
  CurJ, OldJ : double;
  Err, MinErr : double;
  NumCorrect : integer;

  proposal : array of array of integer;
  centroid : array of array of double;
  distance : array of array of double;
  solution : array of integer;

  procedure RandomPick;
  var
    p, q, r : integer;
  begin
    for p := 0 to NumClass-1 do begin
      if p = 0 then
        r := Random(Length(FData))
      else
        r := r + Random((Length(FData)-r));

      for q := 0 to FeatureLength-1 do
        centroid[p][q] := FData[r].feature[q];
    end;
  end;

  procedure CalculateDistanceFromCentroids;
  var
    i, j, k : integer;
    tmp : double;
  begin
    for j := 0 to High(FData) do
      for i := 0 to NumClass-1 do begin
        tmp := 0.0;
        for k := 0 to FeatureLength-1 do
          tmp := tmp + sqr(FData[j].feature[k]-centroid[i][k]);
        distance[j][i] := sqrt(tmp);
      end;
  end;

  procedure Initialize;
  var
    p : integer;
  begin
    NumStep := 0;
    MaxStep := 3000;
    MinErr  := MAXINT;
    OldJ    := MAXINT;

    setlength(proposal, NumClass);
    setlength(centroid, NumClass);
    for p := 0 to NumClass-1 do begin
      setlength(proposal[p], 0);
      setlength(centroid[p], FeatureLength);
    end;

    setlength(solution, Length(FData));
    setlength(distance, Length(FData));
    for p := 0 to high(FData) do
      Setlength(distance[p], NumClass);

    RandomPick;
    CalculateDistanceFromCentroids;
  end;

  procedure CalculateCentroid;
  var
    i, j, k : integer;
    NumInstances : integer;
  begin
    for j := 0 to NumClass-1 do begin
      NumInstances := 0;
      for k := 0 to FeatureLength-1 do
          centroid[j][k] := 0.0;

      for i := 0 to High(proposal[j]) do begin
        for k := 0 to FeatureLength-1 do
          centroid[j][k] := centroid[j][k] + FData[proposal[j][i]].feature[k];
        Inc(NumInstances);
      end;

      if NumInstances &gt; 0 then
        for k := 0 to FeatureLength-1 do
          centroid[j][k] := centroid[j][k] / NumInstances;
    end;
    CalculateDistanceFromCentroids;
  end;

  function IsConverge:boolean;
  var
    i, j : integer;
  begin
    CurJ := 0;
    for i := 0 to NumClass-1 do
      for j := 0 to High(proposal[i]) do
        CurJ := CurJ + distance[proposal[i][j]][i];

    Result := (Abs(CurJ-OldJ) &lt; 1e-2);
    OldJ := CurJ;
  end;

  procedure ReviseMinimum;
  var
    i, j, p, minidx : integer;
    min : double;
  begin
    for p := 0 to NumClass-1 do
      setlength(proposal[p], 0);

    for j := 0 to High(FData) do begin
      minidx := 0;
      min := distance[j][minidx];
      for i := 1 to NumClass-1 do
        if distance[j][i] &lt; min then begin
          minidx := i;
          min := distance[j][minidx];
        end;
      setlength(proposal[minidx], length(proposal[minidx])+1);
      proposal[minidx][high(proposal[minidx])] := j;
    end;
  end;

  procedure MeasureAccuracy;
  var
    i, j : integer;
    parsolution : array of integer;
  begin
    NumCorrect := 0;
    setlength(parsolution, Length(FData));
    for i := 0 to NumClass-1 do
      for j := 0 to High(proposal[i]) do
        parsolution[proposal[i][j]] := i+1;

    for i := 0 to High(FData) do
      if (parsolution[i] = FData[i].truth) then
        Inc(NumCorrect);

    Err := (Length(FData)-NumCorrect) * 100 / Length(FData);
    if Err &lt; MinErr then begin
      MinErr := Err;
      for j := 0 to High(FData) do
        solution[j] := parsolution[j];
    end;
    Setlength(parsolution, 0);
  end;
</pre>
<p><strong>Aplikasi</strong><br />
Algoritma nggak seru kalau tidak ada aplikasinya, jadi saya tampilkan skrinsyut aplikasi algoritma k-means untuk kuantisasi warna citra.<br />
<div id="attachment_238" class="wp-caption alignnone" style="width: 510px"><a href="http://pebbie.files.wordpress.com/2008/11/colorseg.jpg"><img src="http://pebbie.files.wordpress.com/2008/11/colorseg.jpg?w=500&#038;h=374" alt="citra asal" title="citra asal" width="500" height="374" class="size-full wp-image-238" /></a><p class="wp-caption-text">citra asal</p></div><br />
<div id="attachment_239" class="wp-caption alignnone" style="width: 510px"><a href="http://pebbie.files.wordpress.com/2008/11/colorseg4.jpg"><img src="http://pebbie.files.wordpress.com/2008/11/colorseg4.jpg?w=500&#038;h=374" alt="citra hasil" title="citra hasil" width="500" height="374" class="size-full wp-image-239" /></a><p class="wp-caption-text">citra hasil</p></div></p>
<p><strong>Penutup</strong><br />
Algoritma k-means clustering walaupun cepat tetapi keakuratannya tidak dijamin. Seringkali algoritma ini mengalami konvergensi prematur. Pada algoritma di atas juga tidak dijamin jarak antara masing-masing centroid tidak merentang sehingga jika ada dua atau lebih kelompok dengan titik pusat massa yang berdekatan atau terdapat kelompok yang tidak memiliki anggota maka hasilnya akan tidak memuaskan.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/234/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=234&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2008/11/13/algoritma-k-means-clustering/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/11/colorseg.jpg" medium="image">
			<media:title type="html">citra asal</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/11/colorseg4.jpg" medium="image">
			<media:title type="html">citra hasil</media:title>
		</media:content>
	</item>
		<item>
		<title>Glowing Image</title>
		<link>http://pebbie.wordpress.com/2008/10/30/glowing-image/</link>
		<comments>http://pebbie.wordpress.com/2008/10/30/glowing-image/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 05:59:35 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[computer graphics]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[glow]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=222</guid>
		<description><![CDATA[Lagi iseng di sela-sela kerjaan, malah bikin implementasi fake glow. Mari bahas triknya tahap demi tahap!


citra asal dikonversi ke greyscale

setengah intensitas bagian atas dipetakan ke intensitas maksimum

lakukan pengaburan/penghalusan supaya intensitas maksimum menyebar ke sekitarnya. salah satu cara yang sedikit ekstrim :

kecilkan ukuran citra hasil langkah sebelumnya menjadi 1/S kali (misal S = 8).
lakukan smoothing/perata-rataan dengan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=222&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://pebbie.files.wordpress.com/2008/10/thr31.jpg"><img src="http://pebbie.files.wordpress.com/2008/10/thr31.jpg?w=500&#038;h=375" alt="" title="thr31" width="500" height="375" class="alignnone size-full wp-image-230" /></a>Lagi iseng di sela-sela kerjaan, malah bikin implementasi fake glow. Mari bahas triknya tahap demi tahap!<br />
<span id="more-222"></span><br />
<div id="attachment_224" class="wp-caption alignnone" style="width: 510px"><a href="http://pebbie.files.wordpress.com/2008/10/marge.jpg"><img src="http://pebbie.files.wordpress.com/2008/10/marge.jpg?w=500&#038;h=375" alt="citra awal" title="citra awal" width="500" height="375" class="size-full wp-image-224" /></a><p class="wp-caption-text">citra awal</p></div></p>
<ol>
<li>citra asal dikonversi ke greyscale</li>
<p><a href="http://pebbie.files.wordpress.com/2008/10/marge8.jpg"><img src="http://pebbie.files.wordpress.com/2008/10/marge8.jpg" alt="citra greyscale" title="citra greyscale" class="alignnone size-full wp-image-225" /></a></p>
<li>setengah intensitas bagian atas dipetakan ke intensitas maksimum</li>
<p><a href="http://pebbie.files.wordpress.com/2008/10/thr1.jpg"><img src="http://pebbie.files.wordpress.com/2008/10/thr1.jpg" alt="" title="thr1" width="500" height="374" class="alignnone size-full wp-image-226" /></a></p>
<li>lakukan pengaburan/penghalusan supaya intensitas maksimum menyebar ke sekitarnya. salah satu cara yang sedikit ekstrim :
<ul>
<li>kecilkan ukuran citra hasil langkah sebelumnya menjadi 1/<strong>S</strong> kali (misal <strong>S</strong> = 8).</li>
<li>lakukan <em>smoothing</em>/perata-rataan dengan filter blur biasa (box kernel)</li>
<li>kembalikan ke ukuran semula (besarkan ukuran menjadi <strong>S</strong> kali)</li>
</ul>
</li>
<p><a href="http://pebbie.files.wordpress.com/2008/10/thr2.jpg"><img src="http://pebbie.files.wordpress.com/2008/10/thr2.jpg" alt="" title="thr2" width="500" height="374" class="alignnone size-full wp-image-227" /></a></p>
<li>Gabung citra asal dengan citra hasil tahap selanjutnya (citra 3). jika citra asal dalam ranah RGB (warna) maka tiap komponen ditambah dengan intensitas citra yang dikalikan dengan faktor skala tertentu (0.0 &#8230; 1.0)</li>
</ol>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/222/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=222&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2008/10/30/glowing-image/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/10/thr31.jpg" medium="image">
			<media:title type="html">thr31</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/10/marge.jpg" medium="image">
			<media:title type="html">citra awal</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/10/marge8.jpg" medium="image">
			<media:title type="html">citra greyscale</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/10/thr1.jpg" medium="image">
			<media:title type="html">thr1</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/10/thr2.jpg" medium="image">
			<media:title type="html">thr2</media:title>
		</media:content>
	</item>
		<item>
		<title>Analisis Citra Comet Assay</title>
		<link>http://pebbie.wordpress.com/2008/09/23/analisis-citra-comet-assay/</link>
		<comments>http://pebbie.wordpress.com/2008/09/23/analisis-citra-comet-assay/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 17:21:28 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[riset]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[comet assay]]></category>
		<category><![CDATA[image analysis]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=212</guid>
		<description><![CDATA[Ini adalah proyek pribadi saya beberapa tahun yang lalu (sekitar tahun 2006) yang (tadinya) disiapkan untuk membantu tugas akhir duwita (yang sekarang menjadi istri saya) di program studi biologi itb. Comet assay merupakan salah satu teknik uji yang dilakukan untuk mengetahui dan memprediksi kerusakan substansi genetik (DNA) baik kualitatif maupun kuantitatif (CMIIW, karena saya bukan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=212&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify">Ini adalah proyek pribadi saya beberapa tahun yang lalu (sekitar tahun 2006) yang (tadinya) disiapkan untuk membantu tugas akhir duwita (yang sekarang menjadi istri saya) di program studi biologi itb. Comet assay merupakan salah satu teknik uji yang dilakukan untuk mengetahui dan memprediksi kerusakan substansi genetik (DNA) baik kualitatif maupun kuantitatif (CMIIW, karena saya bukan mahasiswa biologi <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ). Dinamakan komet karena objek yang terbentuk pada citra menyerupai bentuk komet (memiliki bagian kepala dan ekor). Topik tugas akhir istri saya waktu itu adalah pada sel sperma mencit yang didedah (<em>exposed</em>) dengan kadmium (Cd) yang diketahui terdapat pada rokok. Kerusakan ditunjukkan dengan terbentuknya ekor komet (DNA yang sehat akan berbentuk seperti halo karena rantai DNA-nya masih terhubung). Ekor komet muncul karena potongan DNA yang mengalami kerusakan struktur (<em>single/double strand break</em>) bergerak  melalui pori-pori agarose akibat stimulus proses elektroforesis. Justifikasi visual dari gambar komet yang terbentuk adalah semakin banyak daerah ekor komet dan semakin kecil ukuran kepala komet dibanding luas area ekor maka kerusakan DNA yang terjadi semakin parah. Adapun ukuran analisis yang dipakai untuk memodelkan kerusakan secara kuantitatif ada bermacam-macam diantaranya panjang ekor (<em>tail length</em>) dan <em>tail moment</em>.</p>
<p align="justify">Hal yang menarik perhatian saya waktu itu adalah bahwa pekerjaan yang dilakukan adalah pengolahan dan interpretasi citra. Adapun aplikasi lain yang sudah tersedia baik komersial (COMET) ataupun Open-source(<a href="http://casp.sourceforge.net/">CASP</a>). Aplikasi yang saya buat pun berbasis pada CASP namun saya terpaksa membuat ulang dengan delphi karena saya kesulitan dengan menggunakan <em>library GUI</em> pada CASP (kalau tidak salah menggunakan FOX) dan ada beberapa fitur yang ingin saya tambahkan seperti segmentasi otomatis pada beberapa citra sekaligus dan analisis otomatis terhadap sekumpulan RoI (region of interest) komet yang sudah disegmentasi dan diverifikasi.</p>
<p><span id="more-212"></span><br />
<div id="attachment_213" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2008/09/test04.gif"><img src="http://pebbie.files.wordpress.com/2008/09/test04.gif?w=300&#038;h=300" alt="Gambar 1 Contoh citra dari CASP" title="test04" width="300" height="300" class="size-medium wp-image-213" /></a><p class="wp-caption-text">Gambar 1 Contoh citra dari CASP</p></div></p>
<p align="justify">Pada awalnya cukup mudah untuk melakukan segmentasi kalau menggunakan contoh citra dari CASP (ditampilkan di gambar 1). Namun pada kenyataannya, hasil citra yang didapat tidak terlalu menggembirakan (Gambar 2). Penyebabnya ada banyak hal, diantaranya proses pencitraan (<em>imaging</em>) yang sangat tidak sempurna (menggunakan kamera film yang kemudian didigitalisasi menjadi citra digital), komposisi larutan uji yang kurang tepat sehingga distribusi objek komet menjadi rapat dan terdapat objek noise), dll. Pada awalnya saya sudah menyiapkan untuk fungsi akuisisi langsung (dengan memanfaatkan kamera cctv bawaan mikroskop fluoresens yang terhubung ke tv tuner sehingga bisa diakses menggunakan DirectShow) namun pengadaan tv tuner USB tidak bisa terlaksana dan saya tidak bisa sembarangan mengakses mikroskop karena bertentangan dengan kebijakan biologi (karena saya tidak secara resmi berkepentingan menggunakan perangkat yang aksesnya bagi civitas biologi pun terbatas pada tugas akhir dan penelitian). Sempat juga mengajukan proposal penelitian untuk mempelajari proses terbentuknya komet sehingga prediksi kerusakan bisa lebih akurat sebagai pelengkap dari aplikasi yang saya kembangkan namun sayang proposal tersebut tidak disetujui.</p>
<div id="attachment_214" class="wp-caption alignnone" style="width: 382px"><a href="http://pebbie.files.wordpress.com/2008/09/komet-dwt.jpg"><img src="http://pebbie.files.wordpress.com/2008/09/komet-dwt.jpg?w=372&#038;h=253" alt="Gambar 2 citra komet hasil pengerjaan" title="komet-dwt" width="372" height="253" class="size-full wp-image-214" /></a><p class="wp-caption-text">Gambar 2 citra komet hasil pengerjaan</p></div>
<p align="justify">Aplikasinya pun berevolusi karena digunakan juga untuk kepentingan lain (penelitian Document Image Recognition, dan penelitian untuk <a href="http://www.digitalmarkreader.com">DMR</a>) sehingga saya tidak bisa mempublikasikan aplikasi yang sudah saya buat. </p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/212/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=212&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2008/09/23/analisis-citra-comet-assay/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/09/test04.gif?w=300" medium="image">
			<media:title type="html">test04</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/09/komet-dwt.jpg" medium="image">
			<media:title type="html">komet-dwt</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducing PEBCLIPS</title>
		<link>http://pebbie.wordpress.com/2008/09/23/introducing-pebclips/</link>
		<comments>http://pebbie.wordpress.com/2008/09/23/introducing-pebclips/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 16:22:09 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[akademik]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[clips]]></category>
		<category><![CDATA[expert system]]></category>
		<category><![CDATA[gui]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=189</guid>
		<description><![CDATA[Pengalaman pertama saya menggunakan CLIPS [1] adalah ketika saya mengambil mata kuliah sistem berbasis pengetahuan sewaktu S1. Waktu itu saya membuat tugas besar dengan topik sistem untuk penyusun playlist lagu otomatis (sistem pakar music director radio siaran atau ESMooD ~ Expert System for Music Director) yang pakarnya merupakan teman-teman kru di Radio Kampus ITB yang [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=189&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify">Pengalaman pertama saya menggunakan <a href="http://en.wikipedia.org/wiki/CLIPS">CLIPS</a> <sub><a href="http://clipsrules.sourceforge.net/">[1]</a></sub> adalah ketika saya mengambil mata kuliah sistem berbasis pengetahuan sewaktu S1. Waktu itu saya membuat tugas besar dengan topik sistem untuk penyusun playlist lagu otomatis (sistem pakar music director radio siaran atau ESMooD ~ Expert System for Music Director) yang pakarnya merupakan teman-teman kru di <a href="http://radiokampus.ee.itb.ac.id">Radio Kampus ITB</a> yang memang pekerjaan hariannya menyusun playlist lagu untuk keperluan siaran.</p>
<p align="justify">CLIPS yang saya ketahui waktu itu antarmuka dengan penggunanya kalau tidak berbasis console (CLIPS.exe) atau WebCLIPS sedangkan aplikasi sistem pakar yang ingin saya buat adalah program berbasis <em>desktop GUI</em> supaya bisa langsung digunakan (:D). Akhirnya saya menemukan komponen VCL yang membungkus CLIPS.dll sehingga bisa digunakan dalam lingkungan Delphi (:victory:). Karena keterbatasan waktu pengerjaan tugas dan pengetahuan waktu itu, programnya pun dibuat <a href="http://students.itb.ac.id/~kid135/ESMooD_peb.pdf">ala kadarnya</a> saja. Mekanisme yang digunakan di dalamnya hanya melakukan <em>load</em> basis kaidah, fakta awal yang merupakan <em>preference</em> dari seorang music director (MD) dan daftar lagu yang dianggarkan untuk minggu tertentu, lalu menjalankan mesin inferensi tanpa proses interaksi dan hasil playlist didapat dari melakukan <em>dump</em> <em>working memory</em>.</p>
<p align="justify">Beberapa waktu (lebih tepatnya bulan) yang lalu saya mengembangkan aplikasi Desktop GUI sebagai perantara antarmuka untuk CLIPS menggunakan delphi. Aplikasi ini cara kerjanya mirip dengen WEBCLIPS hanya saja untuk mengaksesnya langsung pada desktop. Fasilitas yang sudah tercapai antara lain MessageBox ,Status Message, dan Multi text untuk menampilkan teks, Radio Group, Checkbox, dan InputBox untuk mendapatkan masukan, Fasilitas untuk menyimpan dan membuka session, serta menampilkan daftar fakta dalam bentuk pohon. Kode dan binary sudah saya simpan di <a href="http://code.google.com/p/pebclips">Google</a> tapi dokumentasinya belum ada dan contoh aplikasinya juga (sebetulnya sudah ada aplikasi yang menggunakan pebclips, namun aplikasi itu milik orang lain dan mungkin diniatkan menjadi produk komersil sehingga tidak bisa disertakan). Semoga saja aplikasi ini bisa bermanfaat dan bisa terus dikembangkan. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div id="attachment_209" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2008/09/pebclips.png"><img src="http://pebbie.files.wordpress.com/2008/09/pebclips.png?w=300&#038;h=226" alt="tampilan pebclips" title="pebclips" width="300" height="226" class="size-medium wp-image-209" /></a><p class="wp-caption-text">tampilan pebclips</p></div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/189/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/189/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/189/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/189/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/189/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/189/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/189/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/189/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/189/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/189/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=189&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2008/09/23/introducing-pebclips/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/09/pebclips.png?w=300" medium="image">
			<media:title type="html">pebclips</media:title>
		</media:content>
	</item>
		<item>
		<title>OpenMP a la Delphi</title>
		<link>http://pebbie.wordpress.com/2008/09/23/openmp-a-la-delphi/</link>
		<comments>http://pebbie.wordpress.com/2008/09/23/openmp-a-la-delphi/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 15:54:21 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[multithread]]></category>
		<category><![CDATA[parallel programming]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=199</guid>
		<description><![CDATA[Setelah beberapa tulisan[1][2] mengenai OpenMP sebagai bahan kuliah saya jadi penasaran untuk membuat tiruannya dengan Delphi berhubung Delphi (saya pakai versi 7) memiliki kelas wrapper untuk menggunakan fasilitas threading di Win32. Sebetulnya Delphi versi 7 sudah lumayan tertinggal (mengingat sekarang sudah ada Delphi 200X)  dalam hal pengembangan (tapi belum tahu juga untuk versi Turbo [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=199&subd=pebbie&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="justify">Setelah beberapa tulisan<sup><a href="http://pebbie.wordpress.com/2008/09/11/openmp-hello-world-a-la-gaiblog/">[1]</a><a href="http://pebbie.wordpress.com/2008/09/18/gravitational-n-body-simulation/">[2]</a></sup> mengenai <a href="http://openmp.org">OpenMP</a> sebagai bahan kuliah saya jadi penasaran untuk membuat <em>tiruannya</em> dengan Delphi berhubung Delphi (saya pakai versi 7) memiliki kelas <em>wrapper</em> untuk menggunakan fasilitas <em>threading</em> di Win32. Sebetulnya Delphi versi 7 sudah lumayan tertinggal (mengingat sekarang sudah ada Delphi 200X)  dalam hal pengembangan (tapi belum tahu juga untuk versi Turbo Delphi) dan untuk varian lainnya adalah FreePascal tetapi alternatif yang diajukan di FreePascal sepertinya tidak kompatibel secara bahasa dengan versi Object Pascal yang digunakan di Delphi 7 jadinya saya masih ragu-ragu. Akhirnya saya teruskan niat untuk mencoba membuat implementasi dari <em>secuil</em> fitur paralelisme OpenMP yaitu parallel for (untuk modifikasi sekumpulan data yang independen).</p>
<p><span id="more-199"></span><br />
<strong>Pendahuluan</strong></p>
<p align="justify">Langkah pertama adalah membuat algoritma sekuensial yang ingin diparalelkan (dibuat menjadi algoritma yang berjalan secara paralel). Algoritma yang saya pilih adalah seperti tulisan <a href="http://pebbie.wordpress.com/2008/09/11/openmp-hello-world-a-la-gaiblog/">ini</a> yaitu operasi terhadap seluruh elemen <em>array</em> 2 dimensi (misalnya citra) yang hanya melibatkan masing-masing elemen tersebut. Kodenya kira-kira seperti ini (yang dicetak miring adalah operasi elementernya)</p>
<pre class="brush: delphi;">for j := 0 to high(arr) do
    for i := 0 to high(arr[j]) do begin
      arr[j][i] := arr[j][i] + 10; { operasi elementer }
    end;</pre>
<p align="justify">Algoritma ini dipilih karena dianggap cukup sederhana karena jika diimplementasi secara paralel menggunakan <em>thread</em> maka antar <em>thread</em> tidak perlu melakukan komunikasi. Algoritma di atas cukup (bahkan mungkin terlalu) sederhana sehingga tidak bisa dibandingkan dengan algoritma paralel karena untuk membuat algoritma versi paralel ada <em>overhead</em> untuk penciptaan thread, penjadwalan, delegasi tugas, dan pembersihan. Oleh sebab itu yang dijadikan acuan untuk melakukan perbandingan performa adalah algoritma versi paralel yang hanya dikerjakan oleh satu buah <em>thread</em> saja. Waktu eksekusi untuk satu <em>thread</em> ini selanjutnya disebut sebagai t<sub>1</sub> sedangkan waktu eksekusi algoritma versi paralel dengan <strong>n</strong> buah thread akan disebut sebagai t<sub>n</sub> sehingga pemercepatan (peningkatan kecepatan) akan dihitung sebagai perbandingan antara t<sub>1</sub> dengan t<sub>n</sub> (t<sub>1</sub>/t<sub>n</sub>).</p>
<p><strong>Pembuatan kelas <em>Worker Thread</em></strong></p>
<p align="justify">Penggunaan fasilitas <em>threading</em> di Delphi ada dua macam cara. Cara pertama adalah memanfaatkan fungsi-fungsi yang berkaitan dengan <em>thread</em> pada <em>Win32 API</em> dan cara kedua adalah membuat kelas turunan dari kelas <strong>TThread</strong>. Cara kedua dipilih secara subjektif dengan alasan kenyamanan pengelolaan.  Pembuatan kelas turunan TThread dapat memanfaatkan wizard dari delphi dengan menggunakan menu File&gt;New&gt;Other&gt;Thread Object. Fungsi yang ingin dijalankan pada thread ditempatkan sebagai fungsi execute yang menutup(<em>override</em>) implementasi dari kelas TThread. Sifat dari penggunaan kelas turunan TThread adalah objek tersebut akan dibebaskan dari memori setelah fungsi execute selesai dijalankan. Penciptaan dan Pembebasan ini tentunya akan menyebabkan redundansi proses yang tidak terlalu relevan dengan tujuan awal (mempercepat eksekusi). Oleh sebab itu perlu dibuat cara lain sedemikian rupa sehingga objek thread hanya perlu diciptakan sekali sebelum proses utama dilakukan dan hanya perlu sekali dibebaskan dari memori setelah seluruh pekerjaan selesai. Caranya adalah dengan membuat atribut status pada kelas thread dan membuat isi fungsi execute ini melakukan perulangan hingga tercapai status akhir (final state). Untuk itu kita perlu tiga buah keadaan yaitu <em>Running</em>, <em>Idle</em>, dan <em>Done</em>. Pada awalnya keadaan akan diinisialisasi sebagai Idle. Keadaan ini adalah keadaan yang menyatakan objek thread tidak sedang sibuk melakukan pekerjaan sehingga dapat didelegasikan. Jika objek thread sedang sibuk maka keadaannya adalah Running. Kode untuk kelas thread ditunjukkan dalam kode berikut : </p>
<pre class="brush: delphi;">unit Unit2;

interface

uses
  Classes, Windows, SysUtils;

type
  TThreadState = (tsRunning, tsIdle, tsDone);
  TArrElmtModifier = class(TThread)
  private
    { Private declarations }
    FX, FY, FID: integer;
    FState : TThreadState;
  protected
    procedure Execute; override;

    procedure NotifyStart;
    procedure NotifyDone;
  public
    constructor Create(AID:integer);
    procedure Run;
    procedure Done;
    property X : integer read FX write FX;
    property Y : integer read FY write FY;
    property ID : integer read FID write FID;
    property State : TThreadState read FState write FState;
  end;

implementation

uses Unit1;

{ TArrElmtModifier }

constructor TArrElmtModifier.Create(AID:integer);
begin
  inherited Create(false);
  FID := AID;
  X := 0;
  Y := 0;
  State := tsIdle;
  self.FreeOnTerminate := false;
end;

procedure TArrElmtModifier.Done;
begin
  FState := tsDone;
end;

procedure TArrElmtModifier.Execute;
begin
  { Place thread code here }
  while (FState&lt;&gt;tsDone) do begin
    if (FState=tsRunning) then begin
      { Do Thread Task here }
      Form1.arr[Y][X] := Form1.arr[Y][X] + 10;
      NotifyDone;
      { Notify when task done }
    end;
    sleep(1);
  end;
end;

procedure TArrElmtModifier.NotifyDone;
begin
  Form1.AcceptDone(FID);
  State := tsIdle;
end;

procedure TArrElmtModifier.NotifyStart;
begin
  Form1.Memo1.Lines.Add('Thread #'+inttostr(FID)+' started');
end;

procedure TArrElmtModifier.Run;
begin
  State := tsRunning;
end;

end.
</pre>
<p><strong>Implementasi <em>Parallel for</em></strong></p>
<p align="justify">Langkah selanjutnya adalah melakukan penjadwalan untuk alokasi pekerjaan dalam iterasi for agar dikerjakan oleh <em>worker thread</em>. Penyederhanaan (tanpa menggunakan antrian pekerjaan) dilakukan dengan penurunan tiap pekerjaan langsung diturunkan dari pola perulangan yang sama seperti pada algoritma sekuensial sehingga urutan pekerjaan menjadi terurut sesuai dengan eksekusi for. Selanjutnya dilakukan penjadwalan delegasi <em>thread</em> agar tiap <em>thread</em> mendapatkan proporsi beban pekerjaan yang cukup seimbang satu sama lain. Hal ini dilakukan dengan menggunakan antrian berbentuk cincin (ring queue) yang secara sederhana diimplementasi dengan memanfaatkan operator modulo pada struktur data kumpulan objek <em>thread</em> yang menggunakan <em>array</em>. Setelah semua pekerjaan didelegasikan perlu dibuat mekanisme <em>barrier</em> yang akan menunggu konfirmasi penyelesaian dari seluruh thread sebelum thread dibebaskan dari memori. Langkah terakhir adalah menampilkan perubahan. Hasil implementasi pada kode utama ditampilkan sebagai berikut :</p>
<pre class="brush: delphi;">unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit2, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    SpinEdit1: TSpinEdit;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    SpinEdit2: TSpinEdit;
    Button1: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    nthreads : integer;
    threadflags : array of boolean;
    threads : array of TArrElmtModifier;
    arr : array of array of integer;
    tq : integer;
    procedure Prepare;
    procedure DispatchThreads;
    procedure AcceptDone(idx:integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AcceptDone(idx: integer);
begin
  threadflags[idx] := false;
  //memo1.lines.Add('done #'+inttostr(idx));
end;

procedure TForm1.DispatchThreads;
var
  i, j, k : integer;
  busy : boolean;
  tmp : tstrings;
  start, finish : longint;
begin
  Memo1.Lines.Clear;
  start := GetTickCount;

  { ordered scheduling }
  for j := 0 to high(arr) do
    for i := 0 to high(arr[j]) do begin
      { schedule iteration(i,j) }
      busy := true;
      repeat
        k := tq; //GetNextAvailableThread
        //if not threadflags[k] then begin
        if threads[k].State = tsIdle then begin
          threadflags[k] := true;
          //memo1.lines.add(format('dispatch (%d,%d) to thread #%d', [i,j,k]));
          threads[k].X := i;
          threads[k].Y := j;
          threads[k].Run;
          busy := false;
          break;
        end;
        tq := (tq + 1) mod length(threads);
        Application.ProcessMessages;
      until not busy;
    end;

  { barrier, wait until all task finished }
  repeat
    busy := false;
    for k := 0 to high(threads) do begin
      if threadflags[k] then begin
        busy := true;
        break;
      end;
    end;
    Application.ProcessMessages;
  until not busy;
  finish := GetTickCount;
  { clean up threads }
  for i := 0 to high(threads) do
    threads[i].State := tsDone;

  { display changes }
  tmp := TStringlist.Create;
  for j := 0 to high(arr) do begin
    tmp.Clear;
    for i := 0 to high(arr[j]) do begin
      tmp.add(inttostr(arr[j][i]));
    end;
    memo1.Lines.add(tmp.CommaText);
  end;
  Memo1.Lines.Add('Done in '+inttostr(finish-start)+' ms');
  tmp.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i : integer;
begin
  Prepare;

  nthreads := SpinEdit1.Value;
  setlength(threadflags, nthreads);
  setlength(threads, nthreads);
  for i := 0 to high(threads) do begin
    threadflags[i] := false;
    threads[i] := TArrElmtModifier.Create(i);
  end;

  DispatchThreads;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, k : integer;
  start, finish : cardinal;
  tmp : TStrings;
begin
  Prepare;
  Memo1.Lines.Clear;
  start := GetTickCount;

  { ordered scheduling }
  for j := 0 to high(arr) do
    for i := 0 to high(arr[j]) do begin
      arr[j][i] := arr[j][i] + 10;
    end;

  finish := GetTickCount;

  { display changes }
  tmp := TStringlist.Create;
  for j := 0 to high(arr) do begin
    tmp.Clear;
    for i := 0 to high(arr[j]) do begin
      tmp.add(inttostr(arr[j][i]));
    end;
    memo1.Lines.add(tmp.CommaText);
  end;
  Memo1.Lines.Add('Done in '+inttostr(finish-start)+' ms');
  tmp.Free;
end;

procedure TForm1.Prepare;
var
  i,n : integer;
begin
  n := SpinEdit2.Value;

  if length(arr)&gt;0 then
    for i := 0 to high(arr) do
      setlength(arr[i], 0);

  setlength(arr, n);
  for i := 0 to high(arr) do
    setlength(arr[i], n);
  tq := 0;
end;

end.</pre>
<div id="attachment_205" class="wp-caption alignnone" style="width: 417px"><a href="http://pebbie.files.wordpress.com/2008/09/thread.png"><img src="http://pebbie.files.wordpress.com/2008/09/thread.png?w=407&#038;h=502" alt="Tampilan Form (4K PNG)" title="Tampilan Form" width="407" height="502" class="size-full wp-image-205" /></a><p class="wp-caption-text">Tampilan Form (4K PNG)</p></div>
<p><strong>Pengujian</strong></p>
<p align="justify">Untuk menguji perubahan kecepatan pada penggunaan thread digunakan dimensi array 10&#215;10 dan jumlah thread yang diuji antara lain 1 (kontrol), 2, 4, 8, 16 (diabaikan karena asimtotik). Hasil pengukuran ditunjukkan pada gambar berikut.</p>
<div id="attachment_206" class="wp-caption alignnone" style="width: 527px"><a href="http://pebbie.files.wordpress.com/2008/09/speedup.png"><img src="http://pebbie.files.wordpress.com/2008/09/speedup.png?w=517&#038;h=318" alt="Grafik Speedup (4K PNG)" title="Grafik Speedup" width="517" height="318" class="size-full wp-image-206" /></a><p class="wp-caption-text">Grafik Speedup (4K PNG)</p></div>
<p><strong>Penutup</strong></p>
<p align="justify">Sepertinya bisa dinyatakan berhasil, walaupun sebelumnya saya coba justru bisa dibilang gagal karena penggunaan <em>multithread</em> justru memperlambat (mungkin karena saya menjalankan langsung dari IDE). Selanjutnya mungkin saya akan mencoba bagaimana mengimplementasi pola eksekusi berbentuk pohon, analisis statik independensi antar operasi, dan komunikasi (sinkronisasi) antar thread yang pada tujuan akhirnya adalah mewujudkan salah satu mimpi saya terdahulu yaitu membuat bahasa pemrograman (<em>next generation programming language</em>) paralel (akhirnya tujuan perancangannya bisa lebih spesifik) yang memanfaatkan threading secara implisit (tidak perlu menyatakan pembuatan dan pembersihan objek thread secara eksplisit dalam kode program) dan sebisa mungkin makin meng-eksplisitkan independensi antar data/task pada kode program dan penulisan yang bersih dan nyaman untuk dibaca (yang terakhir agak subjektif dan kurang terdefinisi, hehehe). Perwujudan ini (mungkin) dilakukan dalam beberapa tahap yaitu pengembangan abstract machine (sebagai testbed komputer paralel), interpreter, dan pada akhirnya implementasi compiler dan IDE untuk bahasa baru ini yang untuk sementara saya namakan sebagai &#8216;project pi&#8217; (akhirnya ada juga namanya). </p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/199/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/199/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/199/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/199/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/199/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/199/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/199/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/199/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/199/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/199/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&blog=944265&post=199&subd=pebbie&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2008/09/23/openmp-a-la-delphi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0bf1c3f23d84daac10f463f6f0172802?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/09/thread.png" medium="image">
			<media:title type="html">Tampilan Form</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2008/09/speedup.png" medium="image">
			<media:title type="html">Grafik Speedup</media:title>
		</media:content>
	</item>
	</channel>
</rss>