<?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>Notes</title>
	<atom:link href="http://pramook.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pramook.wordpress.com</link>
	<description>Notes on Maths, Computer Graphics, Programming, etc...</description>
	<lastBuildDate>Mon, 16 May 2011 15:48:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='pramook.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Notes</title>
		<link>http://pramook.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://pramook.wordpress.com/osd.xml" title="Notes" />
	<atom:link rel='hub' href='http://pramook.wordpress.com/?pushpress=hub'/>
		<item>
		<title>CMake: การเรียกใช้ไลบรารีภายนอก กรณีศึกษา OpenGL และ GLUT</title>
		<link>http://pramook.wordpress.com/2010/05/12/cmake-%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%84%e0%b8%a5%e0%b8%9a%e0%b8%a3%e0%b8%b2%e0%b8%a3%e0%b8%b5%e0%b8%a0%e0%b8%b2%e0%b8%a2/</link>
		<comments>http://pramook.wordpress.com/2010/05/12/cmake-%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%84%e0%b8%a5%e0%b8%9a%e0%b8%a3%e0%b8%b2%e0%b8%a3%e0%b8%b5%e0%b8%a0%e0%b8%b2%e0%b8%a2/#comments</comments>
		<pubDate>Wed, 12 May 2010 16:26:58 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[cmake]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[opengl]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=301</guid>
		<description><![CDATA[แม้ปัจจุบันมีไลบรารีภาษา C/C++ ที่สามารถใช้ได้บนแพลตฟอร์มพลายแพลตฟอร์มอยู่มากมาย แต่การใช้ไลบรารีเหล่านั้นพัฒนาโปรแกรมยังเป็นเรื่องที่ยุ่งยาก เนื่องจากแพลตฟอร์มต่างๆ เก็บไลบรารีเหล่านี้ไว้ที่ไดเรคต่างๆ กัน CMake มีสคริปต์สำหรับค้นหาแตำแหน่งของไลบรารีที่ได้รับความนิยมอยู่หลายๆ ไลบรารี ทำให้การใช้ไลบรารีเหล่านี้เขียนโปรแกรมที่ใช้ได้หลายๆ แพลตฟอร์มเป็นเรื่องง่าย (แต่ก็ยังมีรายละเอียดมากพอสมควร) ในบทความนี้เราจะมาศึกษาวิธีการเรียกใช้สคริปต์เหล่านี้โดยใช้ไลบรารี OpenGL และ GLUT เป็นตัวอย่าง ติดตั้ง GLUT บน Windows สร้างไดเรคทอรีสำหรับเก็บไลบรารี หากผู้อ่านใช้ Linux หรือ Mac OS X ก็ไม่มีความจำเป็นจะต้องติดตั้งไลบรารีสองไลบรารีข้างต้นแต่อย่างใด เนื่องจากมันติดมากับระบบปฏิบัติการแล้ว อย่างไรก็ดีผู้อ่านที่ใช้ Windows จะต้องมีการติดตั้ง GLUT ให้ CMake สามารถค้นหาเจอได้ วิธีการติดตั้งนี้ความจริงแล้วมีหลายวิธี แต่ผู้เขียนจะนำเสนอวิธีการติดตั้งของตัวเองไว้ &#8230; <a href="http://pramook.wordpress.com/2010/05/12/cmake-%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%84%e0%b8%a5%e0%b8%9a%e0%b8%a3%e0%b8%b2%e0%b8%a3%e0%b8%b5%e0%b8%a0%e0%b8%b2%e0%b8%a2/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=301&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>แม้ปัจจุบันมีไลบรารีภาษา C/C++ ที่สามารถใช้ได้บนแพลตฟอร์มพลายแพลตฟอร์มอยู่มากมาย แต่การใช้ไลบรารีเหล่านั้นพัฒนาโปรแกรมยังเป็นเรื่องที่ยุ่งยาก เนื่องจากแพลตฟอร์มต่างๆ เก็บไลบรารีเหล่านี้ไว้ที่ไดเรคต่างๆ กัน CMake มีสคริปต์สำหรับค้นหาแตำแหน่งของไลบรารีที่ได้รับความนิยมอยู่หลายๆ ไลบรารี ทำให้การใช้ไลบรารีเหล่านี้เขียนโปรแกรมที่ใช้ได้หลายๆ แพลตฟอร์มเป็นเรื่องง่าย (แต่ก็ยังมีรายละเอียดมากพอสมควร) ในบทความนี้เราจะมาศึกษาวิธีการเรียกใช้สคริปต์เหล่านี้โดยใช้ไลบรารี <a href='http://en.wikipedia.org/wiki/OpenGL'>OpenGL</a> และ <a href='http://en.wikipedia.org/wiki/GLUT'>GLUT</a> เป็นตัวอย่าง</p>
<p><span id="more-301"></span></p>
<h2 id='_glut__windows'>ติดตั้ง GLUT บน Windows</h2>
<h3 id='id7'>สร้างไดเรคทอรีสำหรับเก็บไลบรารี</h3>
<p>หากผู้อ่านใช้ Linux หรือ Mac OS X ก็ไม่มีความจำเป็นจะต้องติดตั้งไลบรารีสองไลบรารีข้างต้นแต่อย่างใด เนื่องจากมันติดมากับระบบปฏิบัติการแล้ว อย่างไรก็ดีผู้อ่านที่ใช้ Windows จะต้องมีการติดตั้ง GLUT ให้ CMake สามารถค้นหาเจอได้ วิธีการติดตั้งนี้ความจริงแล้วมีหลายวิธี แต่ผู้เขียนจะนำเสนอวิธีการติดตั้งของตัวเองไว้ ณ ที่นี้</p>
<p>ผู้เขียนได้สร้างไดเรคทอรีหนึ่งในฮาร์ดดิสก์ไว้สำหรับเก็บไลบรารีภาษา C/C++ โดยเฉพาะ ในบทความนี้ขอสมมติให้เป็นไดเรคทอรี <code>C:\usr\local</code> เพื่อให้คล้ายๆ กับไดเรคทอรีใน Unix ในไดเรคทอรีนี้จะได้เรคทอรีย่อดังสองไดเรคทอรีที่สำคัญคือ</p>
<ul>
<li><code>C:\usr\local\include</code> สำหรับเก็บ header file</li>
<li><code>C:\usr\local\lib</code> สำหรับเก็บไลบรารีที่อยู่ในรูปไฟล์ <code>.lib</code></li>
<li><code>C:\usr\local\bin</code> สำหรับเก็บไลบรารีที่อยู่ในรูปไฟล์ <code>.dll</code></li>
</ul>
<p>หลังจากนั้นผู้เขียนจะกำหนด environmental variable ของ Windows สองตัวดังต่อไปนี้ (คุณสามารถดูวิธีกำหนด environmental variable ได้ที่ <a href='http://vlaurie.com/computers2/Articles/environment.htm'>เวบไซต์นี้</a>)</p>
<ul>
<li>เพิ่ม <code>C:\usr\local\bin</code> เข้าในตัวแปร <code>PATH</code> ซึ่งมีอยู่แล้ว</li>
<li>สร้างตัวแปร <code>CMAKE_PREFIX_PATH</code> ใหม่และให้มันมีค่าเท่ากับ <code>C:\usr\local</code></li>
</ul>
<p>CMake จะดูค่าของตัวแปร <code>CMAKE_PREFIX_PATH</code> เวลามันค้นหาไดเรคทอรีของไลบรารีต่างๆ การกำหนด <code>CMAKE_PREFIX_PATH</code> ไม่มีความจำเป็นใน Linux หรือ Mac OS เนื่องจากแพลตฟอร์มเหล่านั้นมี<a href='http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard'>มาตรฐานโครงสร้างไดเรคทอรี</a>กำหนดอยู่ตายตัว ไม่เหมือนกับ Windows</p>
<h3 id='_glut'>ลง GLUT</h3>
<p>คุณสามารถดาวน์โหลด GLUT สำหรับ Windows ได้ที่<a href='http://www.xmission.com/~nate/glut.html'>เวบไซต์ของ Nate Robins</a> เราแนะนำให้คุณดาวน์โหลด <code>glut-3.7.6-bin.zip</code> มาแล้วขยายมันออก แล้วให้คัดลอกไฟล์เหล่านี้ใส่ไดเรคทอรีดังต่อไปนี้</p>
<ul>
<li><code>glut32.dll</code> ลงใน <code>C:\usr\local\bin</code></li>
<li><code>glut32.lib</code> ลงใน <code>C:\usr\local\lib</code></li>
<li><code>glut.h</code> ลงใน <code>C:\usr\local\include\GL</code> โดยที่คุณต้องสร้างไดเรคทอรี <code>C:\usr\local\include\GL</code> ขึ้นมาก่อน</li>
</ul>
<h2 id='id8'>โปรแกรมวาดรูปสี่เหลี่ยมจัตุรัส</h2>
<p>เราจะเขียนโปรแกรม <code>square</code> สำหรับวาดรูปสี่เหลี่ยมจัตุรัสโดยใช้ OpenGL และ GLUT อันดับแรกเราจะสร้างไดเรคทอรีของโปรเจคซึ่งมีไฟล์อยู่ดังต่อไปนี้</p>
<pre><code>sample/
    build/
    src/
        CMakeLists.txt
        config.h.in
        square/
            CMakeLists.txt
            square.cpp</code></pre>
<p>ซึ่งเหมือนกับโครงสร้างไดเรคทอรีใน<a href='http://setbang.moekaku.com/cmake-config-h.html'>บทความเกี่ยวกับการตรวจสอบแพลตฟอร์ม</a>ก่อนหน้านี้ ไฟล์ <code>config.h.in</code> นั้นมีเนื้อหาเหมือนเดิม ที่เปลี่ยนคือไฟล์ <code>CMakeLists.txt</code> ทั้งสองไฟล์ แต่เราจะพูดถึงมันทีหลัง</p>
<p>ไฟล์ <code>square.cpp</code> มีเนื้อหาดังนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='cp'>#include &quot;../config.h&quot;</span>

<span class='cp'>#ifdef __WIN_PLATFORM__</span>
<span class='cp'>#include &lt;windows.h&gt;</span>
<span class='cp'>#endif</span>

<span class='cp'>#ifdef __MAC_PLATFORM__</span>
<span class='cp'>#include &lt;OpenGL/gl.h&gt;</span>
<span class='cp'>#include &lt;OpenGL/glu.h&gt;</span>
<span class='cp'>#include &lt;GLUT/glut.h&gt;</span>
<span class='cp'>#else</span>
<span class='cp'>#include &lt;GL/gl.h&gt;</span>
<span class='cp'>#include &lt;GL/glu.h&gt;</span>
<span class='cp'>#include &lt;GL/glut.h&gt;</span>
<span class='cp'>#endif</span>

<span class='kt'>void</span> <span class='nf'>display</span><span class='p'>()</span>
<span class='p'>{</span>
    <span class='n'>glClearColor</span><span class='p'>(</span><span class='mf'>0.0f</span><span class='p'>,</span> <span class='mf'>0.0f</span><span class='p'>,</span> <span class='mf'>0.0f</span><span class='p'>,</span> <span class='mf'>0.0f</span><span class='p'>);</span>
    <span class='n'>glClearDepth</span><span class='p'>(</span><span class='mf'>1.0f</span><span class='p'>);</span>
    <span class='n'>glClear</span><span class='p'>(</span><span class='n'>GL_COLOR_BUFFER_BIT</span> <span class='o'>|</span> <span class='n'>GL_DEPTH_BUFFER_BIT</span><span class='p'>);</span>
    <span class='n'>glColor3f</span><span class='p'>(</span><span class='mf'>1.0f</span><span class='p'>,</span> <span class='mf'>1.0f</span><span class='p'>,</span> <span class='mf'>1.0f</span><span class='p'>);</span>
    <span class='n'>glBegin</span><span class='p'>(</span><span class='n'>GL_QUADS</span><span class='p'>);</span>
    <span class='n'>glVertex2f</span><span class='p'>(</span><span class='o'>-</span><span class='mf'>0.5f</span><span class='p'>,</span> <span class='o'>-</span><span class='mf'>0.5f</span><span class='p'>);</span>
    <span class='n'>glVertex2f</span><span class='p'>(</span> <span class='mf'>0.5f</span><span class='p'>,</span> <span class='o'>-</span><span class='mf'>0.5f</span><span class='p'>);</span>
    <span class='n'>glVertex2f</span><span class='p'>(</span> <span class='mf'>0.5f</span><span class='p'>,</span>  <span class='mf'>0.5f</span><span class='p'>);</span>
    <span class='n'>glVertex2f</span><span class='p'>(</span><span class='o'>-</span><span class='mf'>0.5f</span><span class='p'>,</span>  <span class='mf'>0.5f</span><span class='p'>);</span>
    <span class='n'>glEnd</span><span class='p'>();</span>
    <span class='n'>glutSwapBuffers</span><span class='p'>();</span>
<span class='p'>}</span>

<span class='kt'>int</span> <span class='nf'>main</span><span class='p'>(</span><span class='kt'>int</span> <span class='n'>argc</span><span class='p'>,</span> <span class='kt'>char</span> <span class='o'>**</span><span class='n'>argv</span><span class='p'>)</span>
<span class='p'>{</span>
    <span class='n'>glutInit</span><span class='p'>(</span><span class='o'>&amp;</span><span class='n'>argc</span><span class='p'>,</span> <span class='n'>argv</span><span class='p'>);</span>
    <span class='n'>glutInitDisplayMode</span><span class='p'>(</span><span class='n'>GLUT_RGBA</span> <span class='o'>|</span> <span class='n'>GLUT_DOUBLE</span> <span class='o'>|</span> <span class='n'>GLUT_DEPTH</span><span class='p'>);</span>
    <span class='n'>glutCreateWindow</span><span class='p'>(</span><span class='s'>&quot;CMake with OpenGL and GLUT&quot;</span><span class='p'>);</span>
    <span class='n'>glutInitWindowSize</span><span class='p'>(</span><span class='mi'>512</span><span class='p'>,</span> <span class='mi'>512</span><span class='p'>);</span>
    <span class='n'>glutDisplayFunc</span><span class='p'>(</span><span class='n'>display</span><span class='p'>);</span>
    <span class='n'>glutMainLoop</span><span class='p'>();</span>
    <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
<span class='p'>}</span>
</code></pre>
</div>
<p>สังเกตว่าในโค้ดข้างบน ก่อนที่ถึงโค้ดที่ทำงานจริง มีโค้ดส่วนหนึ่งที่ใช้ include ไฟล็ที่เหมาะสมซึ่งค่อนข้างยาว (13 บรรทัด) แสดงให้เห็นถึงความยุ่งยากในการเขียนโปรแกรมภาษา C++ ให้ทำงานได้หลายแพลตฟอร์ม ถึงแม้ว่าเราจะมีตัวช่วยอย่าง CMake อยู่ก็ตาม (ดังนั้นจึงไม่แปลกดอกที่คนหันไปใช้ Java หรือ C# มากกว่า)</p>
<p>การใช้ OpenGL และ GLUT มีรายละเอียดพอสรุปได้ดังนี้</p>
<ul>
<li>
<p>แพลตฟอร์มต่างๆ เก็บ OpenGL อยู่คนละที่กัน ดังนั้นเราจึงต้องมีการใช้ preprocessor macro ใน <code>config.h</code> สำหรับตรวจสอบแพลตฟอร์ม และนี่เป็นเหตุผลที่เราต้อง include <code>../config.h</code></p>
</li>
<li>
<p>ใน Windows ก่อนที่เราจะ include <code>GL/gl.h</code> เราจะต้องทำการ include <code>windows.h</code> ก่อนเสมอ แต่ในแพลตฟอร์มอื่นเราไม่ต้องทำเช่นนั้น</p>
</li>
<li>
<p>หากผู้อ่านติดตั้ง GLUT ตามที่ผู้เขียนบอกไว้แล้ว วิธีการ include ไฟล์ของ OpenGL และ GLUT ใน Windows และใน Linux จะมีลักษณะเหมือนกัน กล่าวคือทั้งสามไฟล์อยู่ในไดเรคทอรี <code>GL</code> ซึ่งอยู่ในไดเรคทอรีที่ CMake ไปหา OpenGL และ GLUT เจออีกที</p>
</li>
<li>
<p>ในทางกลับกัน Mac OS เก็บ OpenGL และ GLUT แยกกัน แถมยังเก็บไม่เหมือนของระบบอื่นๆ เลย ทำให้ชื่อไฟล์ header ของ OpenGL ต้องมี <code>OpenGL/</code> นำหน้า ส่วน header ของ GLUT ต้องมี <code>GLUT/</code> นำหน้า</p>
</li>
</ul>
<h2 id='_find_package'>คำสั่ง FIND_PACKAGE</h2>
<p>CMake เรียกไลบรารีภายนอกว่า &#8220;package&#8221; และมีคำสั่ง <code>FIND_PACKAGE</code> ไว้สำหรับค้นหาที่อยู่และข้อมูลจำเป็นอื่นๆ ของ package ที่ผู้ใช้กำหนด คำสั่ง <code>FIND_PACKAGE</code> มีรูปแบบการใช้ดังต่อไปนี้</p>
<pre><code>FIND_PACKAGE(&lt;ชื่อ package&gt;)</code></pre>
<p>และถ้าหากการคอมไพล์โปรเจคต้องใช้ package ที่เราต้องการหา เราอาจสั่ง</p>
<pre><code>FIND_PACKAGE(&lt;ชื่อ package&gt;) REQUIRED)</code></pre>
<p>เพื่อบอกให้ CMake พิมพ์ข้อความแสดงความผิดพลาดหากหา package ไม่เจอ</p>
<p>ในกรณีของโปรเจคในบทความนี้ เราจะใช้ package สองตัวคือ <code>OpenGL</code> และ <code>GLUT</code> (คุณสามารถดู package อื่นๆ ที่ CMake ค้นหาเป็นได้จาก <a href='http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Standard%20CMake%20Modules'>documentation ของ CMake</a>) ฉะนั้นเราจะต้องมีการเพิ่มสคริปต์สองบรรทัดข้างล่างนี้</p>
<pre><code>FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(GLUT REQUIRED)</code></pre>
<p>ลงในไฟล์ <code>src/CMakeLists.txt</code> ดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='text'>CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(sample)

IF(WIN32)
    SET(__WIN_PLATFORM__ &quot;ON&quot;)
ELSE(WIN32)
    SET(__WIN_PLATFORM__ &quot;OFF&quot;)
ENDIF(WIN32)

IF(UNIX)
    IF(APPLE)
        SET(__MAC_PLATFORM__ &quot;ON&quot;)
        SET(__UNIX_PLATFORM__ &quot;OFF&quot;)
    ELSE(APPLE)
        SET(__MAC_PLATFORM__ &quot;OFF&quot;)
        SET(__UNIX_PLATFORM__ &quot;ON&quot;)
    ENDIF(APPLE)
ELSE(UNIX)
    SET(__MAC_PLATFORM__ &quot;OFF&quot;)
    SET(__UNIX_PLATFORM__ &quot;OFF&quot;)
ENDIF(UNIX)

FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(GLUT REQUIRED)

ADD_SUBDIRECTORY(square)

CONFIGURE_FILE( config.h.in ${CMAKE_SOURCE_DIR}/config.h )
</code></pre>
</div>
<p>สังเกตเราใส่คำสั่ง <code>FIND_PACKAGE</code> ไว้ก่อนการประกาศ target ต่างๆ ทุก target เนื่องจาก target ที่เราประกาศอาจต้องการใช้ package ที่เราหาในภายหลัง</p>
<h2 id='_target__package'>ให้ target เรียกใช้ package</h2>
<p>ก่อนที่เราจะคอมไพล์ target หนึ่งที่เรียกใช้ package หนึ่งได้นั้น เราจะต้องให้ข้อมูลสองประการต่อไปนี้กับคอมไพเลอร์</p>
<ol>
<li>
<p>ไดเรคทอรีที่ให้คอมไพเลอร์ไปหาไฟล์ header ของ package</p>
</li>
<li>
<p>ไฟล์ไลบรารีที่คอมไพเลอร์จะต้องลิงก์เข้ากับผลลัพธ์ที่ได้จากการคอมไพล์ไฟล์ของ target</p>
</li>
</ol>
<p>หลังจากใช้ <code>FIND_PACKAGE</code> หาที่อยู่ของ package แล้ว โดยมากข้อมูลไดเรคทอรีที่อยู่ของไฟล์ header นั้นจะอยู่ในตัวแปรชื่อ <code>&lt;ชือ่ package ตัวพิมพ์ใหญ่&gt;_INCLUDE_DIR</code> และข้อมูลไลบรารีที่จะต้องลิงก์จะอยู่ตัวแปรชื่อ <code>&lt;ชื่อ package ตัวพิมพ์ใหญ่&gt;_LIBRARIES</code> ฉะนั้นชื่อตัวแปรที่เก็บข้อมูลเหล่านี้ของ OpenGL และ GLUT ได้แก่ <code>OPENGL_INCLUDE_DIR</code>, <code>OPENGL_LIBRARIES</code>, <code>GLUT_INCLUDE_DIR</code>, และ <code>GLUT_LIBRARIES</code></p>
<p>เราควรจะบอกข้อมูลข้างต้น<strong>เป็นราย target ไป</strong> เนื่องจาก target แต่ละตัวอาจใช้ package ไม่เหมือนกัน ดังนั้นคำสั่งที่ใช้กำหนดข้อมูลเหล่านี้จึงควรอยู่ใน <code>CMakeLists.txt</code> ของ target แต่ละตัว ในกรณีของโปรแกรม <code>square</code> ไฟล์ <code>CMakeLists.txt</code> ของมันมีเนื้อหาดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='text'>INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR})

ADD_EXECUTABLE(square square.cpp)

TARGET_LINK_LIBRARIES(square ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES})
</code></pre>
</div>
<h3 id='_include_directories'>คำสั่ง INCLUDE_DIRECTORIES</h3>
<p>มีรูปแบบ</p>
<pre><code>INCLUDE_DIRECTORIES(&lt;ไดเรคทอรี 1&gt; &lt;ไดเรคทอรี 2&gt; ...)</code></pre>
<p>โดยที่เราสามารถใส่ไดเรคทอรีกี่ไดเรคทอรีก็ได้ในวงเล็บ หลังจากสั่งคำสั่งนี้แล้ว คอมไพเลอร์จะคอมไพล์ target ทุก target โดยใช้ไดเรคทอรีที่กำหนดในการค้นหาไฟล์ header (_หมายเหตุ:_ จริงๆ แล้วไม่ใช่ target ทุก target เสียทีเดียว แต่เป็นทุก target ในไฟล์ <code>CMakeLists.txt</code> เดียวกัน หรือไฟล์ <code>CMakeLists.txt</code> อื่นๆ ที่ปรากฏอยู่ในไดเรคทอรีย่อยที่ถูกเพิ่มผ่าน <code>ADD_SUBDIRECTORY</code> กล่าวคือ คำสั่ง <code>INCLUDE_DIRECTORIES</code> ที่ปรากฏใน <code>src/square/CMakeLists.txt</code> จะไม่มีผลต่อ target ที่ประกาศใน <code>src/cube/CMakeLists.txt</code> หรือ <code>src/cube/star/CMakeLists.txt</code> เลย)</p>
<h3 id='_target_link_libraries'>คำสั่ง TARGET_LINK_LIBRARIES</h3>
<p>มีรูปแบบ</p>
<pre><code>TARGET_LINK_LIBRARIES(&lt;ชื่อ target&gt; &lt;ไลบรารี 1&gt; &lt;ไลบรารี 2&gt; ...)</code></pre>
<p>โดยที่เราสามารถใส่ไลบรารีลงไปกี่ไลบรารีก็ได้หลังชื่อ target คำสั่ง <code>TARGET_LINK_LIBRARIES</code> นี้เนื่องจากมันต้องใช้ชื่อ target มันจึงถูกเรียกอยู่หลังคำสั่ง <code>ADD_EXECUTABLE</code> หรือ <code>ADD_LIBRARY</code> (ที่เรายังไม่ได้พูดถึง) ซึ่งเป็นตัวสร้าง target เสมอ เมื่อสั่ง <code>TARGET_LINK_LIBRARIES</code> แล้ว target ที่กำหนดจะถูกลิงก์เข้ากับไลบรารีที่เรากำหนดให้</p>
<h2 id='id9'>สรุป</h2>
<p>หากต้องการใช้ไลบรารี (package) ภายนอกให้</p>
<ol>
<li>
<p>สั่ง <code>FIND_PACKAGE(&lt;package&gt;)</code> ใน <code>CMakeLists.txt</code> ของโปรเจค</p>
</li>
<li>
<p>สั่ง <code>INCLUDE_DIRECTORIES(&lt;PACKAGE&gt;_INCLUDE_DIR)</code> ใน <code>CMakeLists.txt</code> ของ target ที่จะต้องใช้ package ก่อนการประกาศ target นั้นด้วย <code>ADD_EXECUTABLE</code> หรือ <code>ADD_LIBRARY</code></p>
</li>
<li>
<p>สั่ง <code>TARGET_LINK_LIBRARIES(&lt;target&gt; &lt;PACKAGE&gt;_LIBRARIES)</code> ใน <code>CMakeLists.txt</code> ของ target หลังประกาศ target แล้ว</p>
</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/301/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=301&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2010/05/12/cmake-%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%80%e0%b8%a3%e0%b8%b5%e0%b8%a2%e0%b8%81%e0%b9%83%e0%b8%8a%e0%b9%89%e0%b9%84%e0%b8%a5%e0%b8%9a%e0%b8%a3%e0%b8%b2%e0%b8%a3%e0%b8%b5%e0%b8%a0%e0%b8%b2%e0%b8%a2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>CMake: config.h และการตรวจสอบแพลตฟอร์ม</title>
		<link>http://pramook.wordpress.com/2010/05/10/cmake-config-h-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b8%95%e0%b8%a3%e0%b8%a7%e0%b8%88%e0%b8%aa%e0%b8%ad%e0%b8%9a%e0%b9%81%e0%b8%9e%e0%b8%a5%e0%b8%95%e0%b8%9f%e0%b8%ad%e0%b8%a3/</link>
		<comments>http://pramook.wordpress.com/2010/05/10/cmake-config-h-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b8%95%e0%b8%a3%e0%b8%a7%e0%b8%88%e0%b8%aa%e0%b8%ad%e0%b8%9a%e0%b9%81%e0%b8%9e%e0%b8%a5%e0%b8%95%e0%b8%9f%e0%b8%ad%e0%b8%a3/#comments</comments>
		<pubDate>Mon, 10 May 2010 18:43:28 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[cmake]]></category>
		<category><![CDATA[config.h]]></category>
		<category><![CDATA[configuration]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=294</guid>
		<description><![CDATA[เราเคยกล่าวไปแล้วในบทความการใช้ CMake เบื้องต้น ว่าปัญหาหนึ่งที่โปรแกรมเมอร์ภาษา C++ ที่ต้องการเขียนโปรแกรมให้รันได้ในหลายแพลตฟอร์มเจอคือการที่แพลตฟอร์มต่างๆ มีไลบรารีและฟังก์ชันให้เรียกใช้ไม่เหมือนกัน ตัวอย่างหนึ่งคือฟังก์ชันสำหรับคืนชื่อไดเรคทอรีที่โปรแกรมทำงานอยู่ปัจจุบัน (current working directory) ซึ่งในระบบปฏิบัติการที่สืบเชื้อสายมาจาก Unix จะมีชื่อว่า getcwd และต้อง include ไฟล์ unistd.h เพื่อใช้งาน แต่ใน Windows ฟังก์ชันนี้กลับมีชื่อว่า _getcwd และต้อง include ไฟล์ direct.h แทน ดังนั้น หากเราจะเขียนโปรแกรม print_cwd ที่พิมพ์ current working directory ออกทางหน้าจอ เราจะต้องรู้ว่าโปรแกรมของถูกคอมไพล์อยู่ในแพลตฟอร์มใด ซึ่งในบทความ CMake &#8230; <a href="http://pramook.wordpress.com/2010/05/10/cmake-config-h-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b8%95%e0%b8%a3%e0%b8%a7%e0%b8%88%e0%b8%aa%e0%b8%ad%e0%b8%9a%e0%b9%81%e0%b8%9e%e0%b8%a5%e0%b8%95%e0%b8%9f%e0%b8%ad%e0%b8%a3/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=294&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>เราเคยกล่าวไปแล้วใน<a href='http://setbang.moekaku.com/cmake-multiple-targets.html'>บทความการใช้ CMake เบื้องต้น</a> ว่าปัญหาหนึ่งที่โปรแกรมเมอร์ภาษา C++ ที่ต้องการเขียนโปรแกรมให้รันได้ในหลายแพลตฟอร์มเจอคือการที่แพลตฟอร์มต่างๆ มีไลบรารีและฟังก์ชันให้เรียกใช้ไม่เหมือนกัน</p>
<p>ตัวอย่างหนึ่งคือฟังก์ชันสำหรับคืนชื่อไดเรคทอรีที่โปรแกรมทำงานอยู่ปัจจุบัน (current working directory) ซึ่งในระบบปฏิบัติการที่สืบเชื้อสายมาจาก Unix จะมีชื่อว่า <code>getcwd</code> และต้อง include ไฟล์ <code>unistd.h</code> เพื่อใช้งาน แต่ใน Windows ฟังก์ชันนี้กลับมีชื่อว่า <code>_getcwd</code> และต้อง include ไฟล์ <code>direct.h</code> แทน</p>
<p><span id="more-294"></span></p>
<p>ดังนั้น หากเราจะเขียนโปรแกรม <code>print_cwd</code> ที่พิมพ์ current working directory ออกทางหน้าจอ เราจะต้องรู้ว่าโปรแกรมของถูกคอมไพล์อยู่ในแพลตฟอร์มใด ซึ่งในบทความ CMake เบื้องต้น ผู้เขียนได้เสนอให้ใช้มาโคร <code>_WIN32</code> เป็นตัวเช็คว่าโปรแกรมถูกคอมไพล์ใน Windows หรือไม่ อย่างไรก็ดีผู้เขียนคิดว่าการใช้ <code>_WIN32</code> ไม่น่าจะเป็นความคิดที่ดี เนื่องจากเราไม่ทราบว่าคอมไพเลอร์ตัวอื่นนอกจาก <code>cl</code> ของไมโครซอฟต์จะนิยาม <code>_WIN32</code> เอาไว้หรือไม่</p>
<p>สิ่งที่เราต้องการคือมาโครซึ่งจะถูกนิยามตามแพลตฟอร์มที่โปรแกรมถูกคอมไพล์ เนื่องจากผู้เขียนเขียนโปรแกรมอยู่ในสามแพลตฟอร์มใหญ่ๆ คือ Windows, Mac, และ Linux (ซึ่งเป็น Unix แบบหนึ่ง)​ผู้เขียนจึงอยากให้มีมาโครต่อไปนี้</p>
<ul>
<li><code>__WIN_PLATFORM__</code> ถูกนิยามก็ต่อเมื่อโปรแกรมถูกคอมไพล์ใน Windows</li>
<li><code>__MAC_PLATFORM__</code> ถูกนิยามก็ต่อเมื่อโปรแกรมถูกคอมไพล์ใน Mac OS</li>
<li><code>__UNIX_PLATFORM__</code> ถูกนิยามก็ต่อเมื่อโปรแกรมถูกคอมไพล์ด้วยระบบปฏิบัติการที่สืบเชื้อสายมาจาก Unix อื่นๆ เช่น Linux แต่ไม่ใช่ Mac OS</li>
</ul>
<p>ตาม<a href='http://www.gnu.org/prep/standards/html_node/Configuration.html'>มาตรฐานการเขียนโค้ดของ GNU</a> แล้ว มาโครที่ใช้สำหรับบอกแพลตฟอร์มเหล่านี้จะถูกบรรจุอยู่ในไฟล์ชื่อ <code>config.h</code> ซึ่งอยู่ในชั้นบนสุดของ source directory ของโปรเจค ไฟล์ <code>config.h</code> นี้จะถูกสร้างขึ้นโดยอัตโนมัติด้วยเครื่องมือชื่อ <a href='http://en.wikipedia.org/wiki/Autoconf'><code>autoconf</code></a> ในบทความนี้เราจะเลียนแบบมาตรฐานของ GNU แต่เราจะใช้ CMake สร้าง <code>config.h</code> แทน</p>
<p>หากมี <code>config.h</code> แล้วซอร์สโค้ดของโปรแกรม <code>print_cwd</code> อาจมีเนื้อหาดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* print_cwd.cpp */</span>

<span class='cp'>#include &quot;../config.h&quot;</span>

<span class='cp'>#ifdef __WIN_PLATFORM__</span>
<span class='cp'>#include &lt;direct.h&gt;</span>
<span class='cp'>#else</span>
<span class='cp'>#include &lt;unistd.h&gt;</span>
<span class='cp'>#endif</span>

<span class='cp'>#include &lt;stdio.h&gt;</span>
<span class='cp'>#include &lt;stdlib.h&gt;</span>

<span class='kt'>int</span> <span class='nf'>main</span><span class='p'>()</span>
<span class='p'>{</span>
    <span class='kt'>char</span> <span class='o'>*</span><span class='n'>buffer</span><span class='p'>;</span>
<span class='cp'>    </span>
<span class='cp'>    #ifdef __WIN_PLATFORM__</span>
    <span class='n'>buffer</span> <span class='o'>=</span> <span class='n'>_getcwd</span><span class='p'>(</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='mi'>0</span><span class='p'>);</span>
<span class='cp'>    #else</span>
    <span class='n'>buffer</span> <span class='o'>=</span> <span class='n'>getcwd</span><span class='p'>(</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='mi'>0</span><span class='p'>);</span>
<span class='cp'>    #endif</span>

    <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%s</span><span class='se'>\n</span><span class='s'>&quot;</span><span class='p'>,</span> <span class='n'>buffer</span><span class='p'>);</span>
    <span class='n'>free</span><span class='p'>(</span><span class='n'>buffer</span><span class='p'>);</span>

    <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
<span class='p'>}</span>
</code></pre>
</div>
<p><em>หมายเหตุ:</em> ที่เรา include <code>../config.h</code> แทนที่จะ include <code>config.h</code> เฉยๆ เป็นเพราะว่าจาก<a href='http://setbang.moekaku.com/cmake-multiple-targets.html'>บทความที่แล้ว</a> เราได้เรียนรู้ว่าควรจัดให้ <code>print_cwd.cpp</code> อยู่ในไดเรคทอรี <code>src/print_cwd</code> เพื่อไม่ให้ไปปนกับไฟล์ของ target อื่นๆ แต่ <code>config.h</code> ควรอยู่ในไดเรคทอรี <code>src</code> เนื่องจากเป็นไฟล์ที่ทุกๆ target จะต้องใช้ร่วมกัน</p>
<p>การสร้างไฟล์ <code>config.h</code> โดยใช้ CMake มีขั้นตอนอยู่สามขั้นตอน</p>
<ol>
<li>
<p>เขียนไฟล์ <code>config.h.in</code> เพื่อใช้เป็นต้นแบบของ <code>config.h</code></p>
</li>
<li>
<p>เขียน <code>CMakeLists.txt</code> เพื่อกำหนดตัวตัวแปรต่างๆ ในการนำไปสร้าง <code>config.h</code></p>
</li>
<li>
<p>เรียกคำสั่ง <code>CONFIGURE_FILE</code> ใน <code>CMakeLists.txt</code> เพื่อสร้าง <code>config.h</code></p>
</li>
</ol>
<h2 id='confighin'>config.h.in</h2>
<p><code>config.h.in</code> ควรอยู่ในไดเรคทอรี <code>src</code> เหมือนกับ <code>config.h</code> ดังนั้นโปรเจคของเราจึงมีโครงสร้างไดเรคทอรีดังต่อไปนี้</p>
<pre><code>sample/
    build/
    src/
        CMakeLists.txt
        config.h.in
        print_cwd/
            CMakeLists.txt
            print_cwd.cpp</code></pre>
<p>ที่ไม่มี <code>config.h</code> เนื่องจากมันยังไม่ถูกสร้างขึ้นจริง</p>
<p>เนื้อหาของไฟล์ <code>config.h.in</code> นั้นเหมือนกับเนื้อหาของ header file ของภาษา C/C++ ธรรมดา แต่มาโครใดที่เราต้องกให้ CMake นิยามตามเงื่อนไขต่างๆ ของแพลตฟอร์ม เราจะใช้คำสั่ง <code>#cmakedefine</code> แทน <code>#define</code> ในกรณีของการนิยามมาโครบอกแพลตฟอร์มสามมาโครข้างต้น เราสามารถเขียน <code>config.h.in</code> ได้ดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* config.h.in */</span>

<span class='cp'>#ifndef __CONFIG_H__</span>
<span class='cp'>#define __CONFIG_H__</span>

<span class='cp'>#cmakedefine __WIN_PLATFORM__</span>
<span class='cp'>#cmakedefine __MAC_PLATFORM__</span>
<span class='cp'>#cmakedefine __UNIX_PLATFORM__</span>

<span class='cp'>#endif</span>
</code></pre>
</div>
<p>เวลา CMake สร้างไฟล์ <code>config.h</code> มันจะเอา <code>config.h.in</code> เป็นต้นฉบับและเปลี่ยนแปลงเฉพาะบรรทัดที่มี <code>#cmakedefine</code> เท่านั้น บรรทัดอื่นๆ จะมีเนื้อหาเหมือนเดิม</p>
<h2 id='cmakeliststxt'>CMakeLists.txt</h2>
<p>ในที่นี้เราจะสนใจเฉพาะไฟล์ <code>CMakeLists.txt</code> ที่อยู่ในไดเรคทอรี <code>src</code> เท่านั้น ไฟล์ <code>CMakeLists.txt</code> ที่อยู่ใน <code>src/print_cwd</code> นั้นมีหน้าที่สร้าง executable ชื่อ <code>print_cwd</code> ซึ่งเนื้อหาของมันจะคล้ายกับไฟล์ <code>CMakeLists.txt</code> ทำนองเดียวกันซึ่งปรากฏอยู่ใน<a href='http://setbang.moekaku.com/cmake-multiple-targets.html'>บทความที่แล้ว</a></p>
<p>ไฟล์ <code>CMakeLists.txt</code> ที่เราสนใจอาจมีเนื้อหาดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='text'>PROJECT(sample)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

IF(WIN32)
    SET(__WIN_PLATFORM__ ON)
ELSE(WIN32)
    SET(__WIN_PLATFORM__ OFF)
ENDIF(WIN32)

IF(UNIX)
    IF(APPLE)
        SET(__MAC_PLATFORM__ ON)
        SET(__UNIX_PLATFORM__ OFF)
    ELSE(APPLE)
        SET(__MAC_PLATFORM__ OFF)
        SET(__UNIX_PLATFORM__ ON)
    ENDIF(APPLE)
ELSE(UNIX)
    SET(__MAC_PLATFORM__ OFF)
    SET(__UNIX_PLATFORM__ OFF)
ENDIF(UNIX)

ADD_SUBDIRECTORY(print_cwd)

CONFIGURE_FILE( config.h.in config.h )
</code></pre>
</div>
<p>สังเกตว่าเนื้อหามีส่วนเพิ่มเติมเข้ามาสองส่วนจากเนื้อหาไฟล์ <code>CMakeListst.txt</code> ที่เราพบในบทความก่อนหน้านี้ ได้แก่</p>
<ul>
<li>ส่วนที่เริ่มจาก <code>IF(WIN32)</code> จงถึง <code>ENDIF(UNIX)</code></li>
<li>คำสั่ง <code>CONFIGURE_FILE</code> ในบรรทัดสุดท้าย</li>
</ul>
<h2 id='id5'>กำหนดค่าให้ตัวแปร</h2>
<p>ส่วนซึ่งเริ่มตั้งแต่ <code>IF(WIN32)</code> ถึง <code>ENDIF(UNIX)</code> ทำหน้าที่นิยามตัวแปร <code>__MAC_PLATFORM__</code>, <code>__WIN_PLATFORM__</code>, และ <code>__UNIX_PLATFORM__</code> ให้มีค่าเป็น &#8220;จริง&#8221; หรือ &#8220;เท็จ&#8221; ที่ถูกต้องตรงตามแพลตฟอร์มที่โปรแกรมถูกคอมไพล์ ส่วนนี้มีหลักษณะคล้ายๆ กับโปรแกรมคอมพิวเตอร์เล็กๆ โปรแกรมหนึ่ง</p>
<p>CMake มีภาษาสคริปต์ที่ทรงพลังพอสมควร ภาษาของ CMake อนุญาตให้เราและกำหนดค่าให้ตัวแปร นอกจานี้ยังมีคำสั่ง if และลูป while ให้ใช้ คุณสามารถดูรายละเอียดของโครงสร้างของภาษาเหล่านี้จาก <a href='http://www.cmake.org/cmake/help/cmake-2-8-docs.html'>documentation ของ CMake</a> หรือจาก<a href='http://kernigh.pbworks.com/CMake'>วิกิของ Kernigh</a></p>
<h3 id='_set'>คำสั่ง SET</h3>
<p>คำสั่งที่เราใช้มีอยู่สองคำสั่งได้แก่คำสั่ง <code>SET</code> ซึ่งใช้กำหนดค่าให้ตัวแปร ซึ่งคำสั่งนี้มีรูปแบบ</p>
<pre><code>SET(&lt;ชื่อตัวแปร&gt; &lt;ค่าของตัวแปร&gt;)</code></pre>
<p>ตัวแปรใน CMake มีค่าเป็นสตริง (string) เท่านั้น ดังนั้นค่า ON และ OFF ที่เรากำหนดให้จริงแล้วจึงเป็นค่าสายอักษร &#8220;ON&#8221; และ &#8220;OFF&#8221;</p>
<h3 id='id6'>ค่าความจริง</h3>
<p>CMake ถือว่าสตริง &#8220;ON&#8221;, &#8220;YES&#8221;, และ &#8220;TRUE&#8221; มีค่าเป็น &#8220;จริง&#8221; และถือว่าสตริง &#8220;OFF&#8221;, &#8220;NO&#8221;, และ &#8220;FALSE&#8221; มีค่าเป็นเท็จ ดังั้นเราอาจจะเปลี่ยน ON เป็น TRUE หรือ ​OFF เป็น NO ก็ได้</p>
<p>(จริงๆ แล้วสตริงที่ไม่ใช่สตริงข้างบนที่อาจมีค่าเป็นจริงหรือเท็จได้อีก กรุณาอ่านวิกิของ Kernigh หากต้องการหาข้อมูลเพิ่มเติม)</p>
<h3 id='_if'>คำสั่ง IF</h3>
<p>คำสั่ง <code>IF</code> ใน CMake มีรูปแบบดังต่อไปนี้</p>
<pre><code>IF(&lt;เงื่อนไข&gt;)
    &lt;กลุ่มคำสั่งที่จะทำเมื่อเงื่อนไขเป็นจริง&gt;
ENDIF(&lt;เงื่อนไข&gt;)</code></pre>
<p>หรือ</p>
<pre><code>IF(&lt;เงื่อนไข&gt;)
    &lt;กลุ่มคำสั่งที่จะทำเมื่อเงื่อนไขเป็นจริง&gt;
ELSE(&lt;เงื่อนไข&gt;)
    &lt;กลุ่มคำสั่งที่จะทำเมื่อเงื่อนไขเป็นเท็จ&gt;
ENDIF(&lt;เงื่อนไข&gt;)</code></pre>
<p>ซึ่งคำสั่งทั้งสองรูปแบบมีความหมายเหมือนกับคำสั่ง if ในภาษาโปรแกรมอื่นๆ</p>
<p>สังเกตว่าเวลาเขียนคำสั่งเหล่านี้ เงื่อนไขที่อยู่ในวงเล็บหลัง <code>IF</code>, <code>ELSE</code>, และ <code>ENDIF</code> จะต้องเป็นเงื่อนไขเดียวกันเสมอ ไม่งั้น CMake จะจับคู่ <code>IF</code> กับ <code>ELSE</code> หรือ <code>ENDIF</code> ไม่ถูก พึงระวังว่า CMake ไม่มีคำสั่ง <code>ELSEIF</code> ให้ใช้ภาษาโปรแกรมทั่วๆ ไป</p>
<h3 id='win32_apple__unix'>WIN32, APPLE, และ UNIX</h3>
<p><code>WIN32</code>, <code>APLLE</code>, และ <code>UNIX</code> เป็นตัวแปรสามตัวที่ CMake กำหนดค่าให้อัตโนมัติก่อนการประมวลผล <code>CMakeLists.txt</code> โดยที่</p>
<ul>
<li><code>WIN32</code> จะมีค่าเป็นจริงก็ต่อเมื่อระบบปฏิบัติการที่ใช้อยู่ในตระกูล Windows</li>
<li><code>APPLE</code> จะมีค่าเป็นจริงก็ต่อเมื่อระบบปฏิบัติการที่ใช้อยู่ในตระกูล Mac OS</li>
<li><code>UNIX</code> จะมีค่าเป็นจริงก็ต่อเมื่อระบบปฏิบัติการที่ใช้สืบเชื้อสายมาจาก Unix</li>
</ul>
<p><em>หมายเหตุ:</em> ผู้เขียนสร้างตัวแปรใหม่สามตัวแทนที่จะใช้ <code>WIN32</code>, <code>APPLE</code>, และ <code>UNIX</code> ไปเลยเนื่องจาก (1) ความหมายของ <code>__UNIX_PLATFORM__</code> ไม่ตรงกับความหมายของ <code>UNIX</code> (<code>UNIX</code> จะเป็นจริงในระบบปฏิบัติการตระกูล MAC OS ด้วย) และ (2) ผู้เขียนเห็นว่าชื่อมาโครที่ไม่มี underscore นำหน้าควรจะถูกเปิดไว้ให้ผู้เขียนโปรแกรมนำไปใช้</p>
<h2 id='_configure_file'>คำสั่ง CONFIGURE_FILE</h2>
<p>คำสั่ง <code>CONFIGURE_FILE</code> มีรูปแบบดังต่อไปนี้</p>
<pre><code>CONFIGURE_FILE(&lt;ชื่อไฟล์ต้นฉบับ&gt; &lt;ชื่อไฟล์ที่ต้องการสร้าง&gt;)</code></pre>
<p>สังเกตว่าเราเขียนคำสั่ง <code>CONFIG_FILE</code> ไว้เป็นคำสั่งสุดท้ายหลังจากการตั้งแต่ตัวแปรและการกำหนด target ต่างๆ (เรากำหนด target ผ่านการสั่ง <code>ADD_DIRECTORY</code>) เนื่องจากคำสั่ง <code>CONFIGURE_FILE</code> จะนำค่าของตัวแปรต่างๆ ณ ตำแหน่งที่ <code>CONFIGURE_FILE</code> ถูกเรียกมาใช้ในการสร้าง <code>config.h</code> ดังนั้นเราจึงเอาคำสั่งนี้ไว้เป็นคำสั่งสุดท้าย เพื่อให้แน่ใจได้ว่าตัวแปรทุกตัวถูกกำหนดไว้เรียบร้อยแล้ว</p>
<p>แต่สังเกตว่าเราไม่ได้ใส่ชื่อ <code>config.h</code> ไว้เฉยๆ แต่เราเติม <code>${CMAKE_SOURCE_DIR}/</code> ไปข้างหน้ามัน ที่เป็นเช่นนี้ก็เพราะว่า<strong>ไฟล์ที่ CMake สร้างจะอยู่ใน binary directory เสมอ เว้นแต่จะกำหนดเป็นอย่างอื่น</strong> แต่เราต้องการให้ <code>config.h</code> อยู่ในไดเรคทอรี <code>src</code> ดังนั้นเราจึงใช้ตัวแปร <code>CMAKE_SOURCE_DIR</code> ซึ่งเป็นไดเรคทอรีที่มีไฟล์ <code>CMakeLists.txt</code> ของโปรเจคอยู่ (ในที่นี้แค่ <code>src</code>) สังเกตอีกอย่างว่าเวลาเราใช้ตัวแปรของ CMake เราจะล้อมชื่อตัวแปรด้วย <code>${</code> และ <code>}</code> เหมือนกับการใช้ตัวแปรใน unix shell ต่างๆ</p>
<p>หากเราอยู่ในระบบปฏิบัติการ Mac OS เราจะได้ <code>src/config.h</code> ที่มีเนื้อหาดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='cp'>#ifndef __CONFIG_H__</span>
<span class='cp'>#define __CONFIG_H__</span>

<span class='c'>/* #undef __WIN_PLATFORM__ */</span>
<span class='cp'>#define __MAC_PLATFORM__</span>
<span class='c'>/* #undef __UNIX_PLATFORM__ */</span>

<span class='cp'>#endif</span>
</code></pre>
</div>
<p>ในทางกลับกันหากเราอยู่ใน Windows แล้ว <code>src/config.h</code> จะมีเนื้อหาดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='cp'>#ifndef __CONFIG_H__</span>
<span class='cp'>#define __CONFIG_H__</span>

<span class='cp'>#define __WIN_PLATFORM__</span>
<span class='c'>/* #undef __MAC_PLATFORM__ */</span>
<span class='c'>/* #undef __UNIX_PLATFORM__ */</span>

<span class='cp'>#endif</span>
</code></pre>
</div>
<p>ซึ่งนิยามมาโครตรงตามความต้องการของเราเป๊ะ</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/294/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=294&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2010/05/10/cmake-config-h-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b8%95%e0%b8%a3%e0%b8%a7%e0%b8%88%e0%b8%aa%e0%b8%ad%e0%b8%9a%e0%b9%81%e0%b8%9e%e0%b8%a5%e0%b8%95%e0%b8%9f%e0%b8%ad%e0%b8%a3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>CMake: เมื่อโปรเจคมีหลาย &#8220;เป้าหมาย&#8221;</title>
		<link>http://pramook.wordpress.com/2010/05/09/cmake-multiple-targets/</link>
		<comments>http://pramook.wordpress.com/2010/05/09/cmake-multiple-targets/#comments</comments>
		<pubDate>Sun, 09 May 2010 22:01:40 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[cmake]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=288</guid>
		<description><![CDATA[ในโปรเจคซอฟต์แวร์หนึ่งๆ อาจมีการสร้างโปรแกรมที่สามารถนำไปรันได้โดยตรง (executable) หรือไลบรารี (library) มากกว่าหนึ่งอันขึ้นไป (เพื่อให้ง่ายต่อการเขียน ผู้เขียนจะเรียกไฟล์ที่คอมไพเลอร์ภาษา C++ สร้างว่า target ตามที่ Xcode เรียก) ซึ่งอาจจะเป็นเพราะ target เหล่านี้เป็นโปรแกรมซึ่งทำงานสนับสนุนซึ่งกันและกัน หรือ target บางตัวเป็นไลบรารีซึ่ง target ตัวอื่นเรียกใช้ ในโพสต์นี้เราจะมาพูดถึงการเขียน CMakeLists.txt เพื่อสร้าง target หลายๆ target ในการ build ครั้งเดียว วิธีการเขียน CMakeLists.txt ให้บรรลุวัตถุประสงค์ข้างบนมีหลายวิธี เราจะนำเสนอวิธีการต่างๆ จากง่ายไปยาก โดยวิธีการที่ง่ายๆ นี้หมายความถึงวิธีการที่เขียนไฟล์ง่ายๆ สั้นๆ ไม่ต้องเสียแรงมาก &#8230; <a href="http://pramook.wordpress.com/2010/05/09/cmake-multiple-targets/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=288&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>ในโปรเจคซอฟต์แวร์หนึ่งๆ อาจมีการสร้างโปรแกรมที่สามารถนำไปรันได้โดยตรง (executable) หรือไลบรารี (library) มากกว่าหนึ่งอันขึ้นไป (เพื่อให้ง่ายต่อการเขียน ผู้เขียนจะเรียกไฟล์ที่คอมไพเลอร์ภาษา C++ สร้างว่า <em>target</em> ตามที่ Xcode เรียก) ซึ่งอาจจะเป็นเพราะ target เหล่านี้เป็นโปรแกรมซึ่งทำงานสนับสนุนซึ่งกันและกัน หรือ target บางตัวเป็นไลบรารีซึ่ง target ตัวอื่นเรียกใช้ ในโพสต์นี้เราจะมาพูดถึงการเขียน <code>CMakeLists.txt</code> เพื่อสร้าง target หลายๆ target ในการ build ครั้งเดียว</p>
<p>วิธีการเขียน CMakeLists.txt ให้บรรลุวัตถุประสงค์ข้างบนมีหลายวิธี เราจะนำเสนอวิธีการต่างๆ จากง่ายไปยาก โดยวิธีการที่ง่ายๆ นี้หมายความถึงวิธีการที่เขียนไฟล์ง่ายๆ สั้นๆ ไม่ต้องเสียแรงมาก แต่ไม่เหมาะสมกับโปรเจคที่มีขนาดไหน ส่วนวิธีการที่ยากนั้นเขียนไฟล์ยาวกว่าและอาจจะต้องมีการสร้างไฟล์ <code>CMakeLists.txt</code> เพิ่มเติม เพื่อให้จัดการโปรเจคที่ซับซ้อนได้ดียิ่งขึ้น</p>
<p><span id="more-288"></span></p>
<h2 id='hello_world__good_morning'>Hello World ปะทะ Good Morning</h2>
<p>สมมติว่าเราจะสร้างโปรเจค <code>sample1</code> ซึ่งมี target สอง target ดังต่อไปนี้</p>
<ul>
<li><code>helloworld</code> เป็นโปรแกรมพิมพ์ข้อความ &#8220;hello, world&#8221; ออกทางหน้าจอ</li>
<li><code>goodmorning</code> เป็นโปรแกรมพิมพ์ข้อความ &#8220;good morning&#8221; ออกทางหน้าจอ</li>
</ul>
<p>ซึ่งมีซอร์สโค้ดเป็นดังต่อไปนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* helloworld.cpp */</span>
<span class='cp'>#include &lt;stdio.h&gt;</span>

<span class='kt'>int</span> <span class='nf'>main</span><span class='p'>()</span>
<span class='p'>{</span>
    <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;hello, world</span><span class='se'>\n</span><span class='s'>&quot;</span><span class='p'>);</span>
    <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
<span class='p'>}</span>
</code></pre>
</div>
<div class='highlight'>
<pre><code class='c'><span class='o'>/*</span> <span class='n'>goodmorning</span><span class='p'>.</span><span class='n'>cpp</span> <span class='o'>%/</span>
<span class='cp'>#include &lt;stdio.h&gt;</span>

<span class='kt'>int</span> <span class='n'>main</span><span class='p'>()</span>
<span class='p'>{</span>
    <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;good morning</span><span class='se'>\n</span><span class='s'>&quot;</span><span class='p'>);</span>
    <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
<span class='p'>}</span>
</code></pre>
</div>
<p>เนื่องจากไฟล์มีอยู่แค่สองไฟล์ เราอาจจะให้ไฟล์ทั้งสองอยู่ในไดเรคทอรีเดียวกันไปเลยดังโครงสร้างไดเรคทอรีข้างล่างนี้</p>
<pre><code>sample1/
    src/
        CMakeLists.txt
        helloworld.cpp
        goodmorning.cpp</code></pre>
<p>และในไฟล์ CMakeLists.txt เราสามารถสั่งให้ CMake สร้าง executable สอง executable ได้ด้วยการสั่ง <code>ADD_EXECUTABLE</code> สองครั้ง</p>
<pre><code>PROJECT(sample2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_EXECUTABLE(helloworld helloworld.cpp)
ADD_EXECUTABLE(goodmorning goodmorning.cpp)</code></pre>
<h2 id='_target_'>หนึ่ง target หนึ่งไดเรคทอรี</h2>
<p>ในการเขียนซอฟต์แวร์ขนาดใหย่ เราอาจพบว่า target สอง target อาจมีการใช้ไฟล์ชื่อเดียวกัน ฉะนั้นเราจึงไม่สามารถใส่ไฟล์ของทุก target ไว้ในไดเรคทอรีเดียวกันได้ ฉะนั้นเพื่อให้ไฟล์จัดการง่าย เราควรจะแยกไฟล์ของ target แต่ละ target ไว้ในไดเรคทอรีของมันเอง</p>
<p>เราอาจจะจำลองสถานการณ์นั้นโดยแยก <code>helloworld.cpp</code> และ <code>goodmorning.cpp</code> เป็นสองส่วน คือ <code>text.h</code> และ <code>main.cpp</code> ดังนี้ (ขออภัยที่การจำลองสถานการ์นี้อาจจะไม่เหมือนจริงไปสักหน่อย)</p>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* text.h ของ helloworld */</span>
<span class='cp'>#include &lt;stdio.h&gt;</span>

<span class='k'>const</span> <span class='kt'>char</span> <span class='o'>*</span><span class='n'>helloworld_text</span> <span class='o'>=</span> <span class='s'>&quot;hello, world</span><span class='se'>\n</span><span class='s'>&quot;</span><span class='p'>;</span>
</code></pre>
</div>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* main.cpp ของ helloworld */</span>
<span class='cp'>#include &quot;text.h&quot;</span>

<span class='kt'>int</span> <span class='nf'>main</span><span class='p'>()</span>
<span class='p'>{</span>
    <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%s&quot;</span><span class='p'>,</span> <span class='n'>helloworld_text</span><span class='p'>);</span>
    <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
<span class='p'>}</span>
</code></pre>
</div>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* text.h ของ goodmorning */</span>
<span class='cp'>#include &lt;stdio.h&gt;</span>

<span class='k'>const</span> <span class='kt'>char</span> <span class='o'>*</span><span class='n'>goodmorning_text</span> <span class='o'>=</span> <span class='s'>&quot;good morning</span><span class='se'>\n</span><span class='s'>&quot;</span><span class='p'>;</span>
</code></pre>
</div>
<div class='highlight'>
<pre><code class='c'><span class='c'>/* main.cpp ของ goodmorning */</span>
<span class='cp'>#include &quot;text.h&quot;</span>

<span class='kt'>int</span> <span class='nf'>main</span><span class='p'>()</span>
<span class='p'>{</span>
    <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;%s&quot;</span><span class='p'>,</span> <span class='n'>goodmorning_text</span><span class='p'>);</span>
    <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
<span class='p'>}</span>
</code></pre>
</div>
<p>เราสามารถจัดไฟล์ตามโครงสร้างไดเรคทอรีต่อไปนี้ได้</p>
<pre><code>sample2/
    src/
        CMakeLists.txt
        helloworld/
            text.h
            main.cpp
        goodmorning/
            text.h
            main.cpp</code></pre>
<p>และเขียนไฟล์ <code>CMakeLists.txt</code> ใหม่ว่า</p>
<pre><code>PROJECT(sample2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_EXECUTABLE(helloworld helloworld/text.h helloworld/main.cpp)
ADD_EXECUTABLE(goodmorning goodmorning/text.h goodmorning.cpp)</code></pre>
<h2 id='__cmakeliststxt'>หนึ่งไดเรคทอรี หนึ่ง CMakeLists.txt</h2>
<p>สังเกตว่าในตัวอย่างที่แล้ว เวลาเราจะใส่ไฟล์เข้าใน executable หนึ่งๆ เราจะต้องใส่ไดเรคทอรีของไฟล์นั้นเข้าไปด้วย เนื่องจากชื่อไฟล์ที่กำหนดใน <code>CMakeLists.txt</code> ใดๆ จะเป็นชื่อไฟล์สัมพัทธ์กับไดเรคทอรีที่ <code>CMakeLists.txt</code> อยู่เสมอ ซึ่งทำให้เกิดความไม่สะดวกอย่างมาก</p>
<p>นอกจากนี้ หาก target ของเราเป็น target ที่มีไฟล์อยู่หลายไฟล์ <code>CMakeLists.txt</code> จะต้องมีชื่อไฟล์เหล่านี้ทั้งหมด ทำให้ <code>CMakeLists.txt</code> มีขนาดใหญ่มาก ทำให้แก้ไขและจัดการยาก</p>
<p>CMake อนุญาตให้เราเขียน <code>CMakeLists.txt</code> ได้หลายๆ ไฟล์​(แต่ในไดเรคทอรีหนึ่งๆ จะมี <code>CMakeLists.txt</code> ได้เพียงไฟล์เดียวเท่านั้น เนื่องจากชื่อไฟล์ซ้ำกันไม่ได้) แล้วให้ไฟล์ <code>CMakeLists.txt</code> ของไดเรคทอรีแม่ไปเอาเนื้อหาของ <code>CMakeLists.txt</code> ในไดเรคทอรีลูกมาประมวลผลได้ ความสามารถนี้ช่วยให้เราสามารถเขียน <code>CMakeLists.txt</code> ของแต่ละ target แยกกันได้หากเราแยกไฟล์ของ target แต่ละตัวอยู่ในไดเรคทอรีของมันแล้ว</p>
<p>เราจะนำตัวอย่างที่แล้วมาดัดแปลงให้ใช้ความสามารถใหม่นี้ อันดับแรกเราจะสร้างไฟล์ <code>CMakeLists.txt</code> ไว้ในไดเรคทอรี <code>helloworld</code> และ <code>goodmorning</code> อย่างละไฟล์ ตามโครงสร้างไดเรคทอรีข้างล่าง</p>
<pre><code>sample3/
    src/
        CMakeLists.txt
        helloworld/
            CMakeLists.txt
            text.h
            main.cpp
        goodmorning/
            CMakeLists.txt
            text.h
            main.cpp</code></pre>
<p>ในไฟล์ <code>CMakeLists.txt</code> ของไดเรคทอรี <code>src</code> เราเปลี่ยนคำสั่ง <code>ADD_EXECUTABLE</code> เป็นคำสั่ง <code>ADD_SUBDIRECTORY</code> เพื่อบอกให้ CMake ไปอ่านและประมวลไฟล์ <code>CMakeLists.txt</code> ในไดเรคทอรีย่อยที่กำหนดให้</p>
<div class='highlight'>
<pre><code class='text'>### sample3/src/CMakeLists.txt

PROJECT(sample3)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_SUBDIRECTORY(helloworld)
ADD_SUBDIRECTORY(goodmorning)
</code></pre>
</div>
<p>ส่วนในไฟล์ <code>CMakeLists.txt</code> ของ <code>helloworld</code> และ <code>goodmorning</code> เราก็ใช้คำสั่ง <code>ADD_EXECUTABLE</code> เหมือนเดิม แต่เราไม่ต้องใส่ชื่อไดเรคทอรีนำหน้าไฟล์ต่างๆ แล้ว เนื่องจาก <code>CMakeLists.txt</code> อยู่ในไดเรคทอรีเดียวกับไฟล์พวกนั้นแล้ว</p>
<div class='highlight'>
<pre><code class='text'>### sample3/src/helloworld/CMakeLists.txt

ADD_EXECUTABLE(helloworld text.h main.cpp)
</code></pre>
</div>
<div class='highlight'>
<pre><code class='text'>### sample3/src/goodmorning/CMakeLists.txt

ADD_EXECUTABLE(goodmorning text.h main.cpp)
</code></pre>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/288/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=288&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2010/05/09/cmake-multiple-targets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>การใช้ CMake เบื้องต้น</title>
		<link>http://pramook.wordpress.com/2010/05/08/basic-cmake/</link>
		<comments>http://pramook.wordpress.com/2010/05/08/basic-cmake/#comments</comments>
		<pubDate>Sat, 08 May 2010 15:53:43 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[cmake]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=278</guid>
		<description><![CDATA[CMake (http://www.cmake.org/ และ http://en.wikipedia.org/wiki/Cmake) เป็นซอฟต์แวร์สำหรับสร้าง build script (ไฟล์ที่นิยามวิธีการคอมไพล์และลิงก์โปรแกรมและไลบรารีที่เขียนด้วยภาษา C++) ที่สามารถใช้ร่วมกับเครื่องมือพัฒนาโปรแกรมที่ได้รับความนิยมหลายๆ ตัว อาทิ Microsoft Visual C++, GNU Compiler Collection, Xcode, และ Eclipse CDT เป็นต้น การใช้ CMake ช่วยให้เรากำหนดซอฟต์แวร์ที่เราต้องการสร้างเพียงครั้งเดียว หลังจากนั้นเราสามารถพัฒนามันโดยใช้เครื่องมือที่เราชอบบนแพลตฟอร์มใดๆ ก็ได้ CMake จึงอำนวยช่วยความสะดวกให้กับโปรแกรมเมอร์ภาษา C++ ที่ต้องการสร้างซอฟต์แวร์ที่รันบนหลายๆ แพลตฟอร์มอย่างมาก ในบทความนี้เราจะกล่าวถึงวิธีการใช้งาน CMake จัดการซอฟต์แวร์โปรเจคง่ายๆ เป็นการปูพื้นฐานก่อนจะกล่าวถึงการใช้งานที่สลับซับซ้อนขึ้นต่อไป ปัญหาของการเขียนโปรแกรมสำหรับหลายแพลตฟอร์ม การเขียนโปรแกรมภาษา C++ &#8230; <a href="http://pramook.wordpress.com/2010/05/08/basic-cmake/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=278&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>CMake (<a href='http://www.cmake.org/'>http://www.cmake.org/</a> และ <a href='http://en.wikipedia.org/wiki/Cmake'>http://en.wikipedia.org/wiki/Cmake</a>) เป็นซอฟต์แวร์สำหรับสร้าง build script (ไฟล์ที่นิยามวิธีการคอมไพล์และลิงก์โปรแกรมและไลบรารีที่เขียนด้วยภาษา C++) ที่สามารถใช้ร่วมกับเครื่องมือพัฒนาโปรแกรมที่ได้รับความนิยมหลายๆ ตัว อาทิ Microsoft Visual C++, GNU Compiler Collection, Xcode, และ Eclipse CDT เป็นต้น</p>
<p>การใช้ CMake ช่วยให้เรากำหนดซอฟต์แวร์ที่เราต้องการสร้างเพียงครั้งเดียว หลังจากนั้นเราสามารถพัฒนามันโดยใช้เครื่องมือที่เราชอบบนแพลตฟอร์มใดๆ ก็ได้ CMake จึงอำนวยช่วยความสะดวกให้กับโปรแกรมเมอร์ภาษา C++ ที่ต้องการสร้างซอฟต์แวร์ที่รันบนหลายๆ แพลตฟอร์มอย่างมาก ในบทความนี้เราจะกล่าวถึงวิธีการใช้งาน CMake จัดการซอฟต์แวร์โปรเจคง่ายๆ เป็นการปูพื้นฐานก่อนจะกล่าวถึงการใช้งานที่สลับซับซ้อนขึ้นต่อไป</p>
<p><span id="more-278"></span></p>
<h2 id='id1'>ปัญหาของการเขียนโปรแกรมสำหรับหลายแพลตฟอร์ม</h2>
<p>การเขียนโปรแกรมภาษา C++ ให้คอมไพล์และรันบนหลายๆ แพลตฟอร์ม (เขียนครั้งเดียวแต่รันได้ทั้งบน Windows, Unix, Mac, ฯลฯ) นั่นเป็นเรื่องที่ทำให้โปรแกรมเมอร์ปวดเศียรเวียนเกล้าอย่างหนักมาหลายคนแล้ว เหตุก็เพราะว่า แพลตฟอร์มต่างๆ กันนั้นมี &#8220;สภาพแวดล้อม&#8221; สำหรับพัฒนาโปรแกรมภาษา C++ ที่ไม่เหมือนกันเอาเสียเลย เราอาจสามารถสรุปปัญหาที่โปรแกรมเมอร์เจอไว้เป็นข้อๆ ได้ดังต่อไปนี้</p>
<ol>
<li>
<p>ไลบรารีภาษา C/C++ บนแพลตฟอร์มต่างๆ ไม่เหมือนกัน เช่น ใน Linux และ Mac จะมีไฟล์ <code>unistd.h</code> แต่ใน Windows ไม่มี หรือใน Mac มีระบบไลบรารีที่เรียกว่า <a href='http://osxbook.com/book/bonus/ancient/whatismacosx//programming.html'>bundle และ framework</a> ซึ่งไม่ปรากฏอยู่ในแพลตฟอร์มอื่นๆ</p>
</li>
<li>
<p>คอมไพเลอร์ที่ใช้เป็นคนละตัวกัน กล่าวคือ โปรแกรมเมอร์ C++ ใน Windows จะใช้ <code>cl</code> ของ Microsoft ส่วนโปรแกรมเมอร์บน Linux และ Mac จะใช้ <code>gcc</code> หรือ <code>g++</code> ของ GNU Project นี่หมายความว่าภาษา C++ ใน Windows จะไม่เหมือนกับภาษา C++ ใน Unix และ Mac เป๊ะ และมีข้อแตกต่างยิบย่อยที่ทำให้ซอร์สโค้ดที่เขียนสำหรับแพลตฟอร์มหนึ่งไม่สามารถคอมไพล์บนอีกแพลตฟอร์มหนึ่งได้</p>
</li>
<li>
<p>เครื่องมือที่ใช้ในการ build โปรแกรมไม่เหมือนกัน โปรแกรมเมอร์บน Windows จะใช้ Visual Studio พวกที่ใช้ Linux ก็จะเขียน Makefile แล้วรัน <code>make</code> ส่วนขา Mac ก็จะใช้ Xcode</p>
</li>
</ol>
<h3 id='preprocessor_macro'>Preprocessor Macro</h3>
<p>เราสามารถหลีกเลี่ยงสองปัญหาแรกบางส่วนได้ด้วยการเขียน <a href='http://en.wikipedia.org/wiki/Preprocessor_macro'>preprocessor macro</a> เพื่อให้คอมไพเลอร์เลือกใช้โค้ดส่วนที่ถูกต้อง ยกตัวอย่าง เช่น หากเราต้องการชื่อของไดเรคทอรีที่โปรแกรมทำงานอยู่ในปัจจุบัน (current working directory ย่อว่า cwd) แล้ว</p>
<ul>
<li>ใน Linux และ Mac เราจะต้องใช้คำสั่ง <code>getcwd</code> ซึ่งอยู่ใน <code>unistd.h</code></li>
<li>แต่ใน Windows เราจะต้องใช้คำสั่ง <code>_getcwd</code> ซึ่งอยู่ใน <code>direct.h</code></li>
</ul>
<p>เนื่องจาก <code>cl</code> จะนิยามมาโคร <code>_WIN32</code> ก่อนคอมไพล์ไฟล์ทุกไฟล์ ดังนั้นเราสามารถเช็คได้ว่า ตอนนี้โปรแกรมถูกคอมไพล์บน Windows หรือแพลตฟอร์มอื่นได้โดยการเช็คว่า <code>_WIN32</code> ถูกนิยามหรือไม่ ฉะนั้นเราสามารถเลือก include ไฟล์ที่ถูกต้องได้ดังนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='cp'> #ifdef _WIN32</span>
<span class='cp'> #include &lt;direct.h&gt;</span>
<span class='cp'> #else</span>
<span class='cp'> #include &lt;unistd.h&gt;</span>
<span class='cp'> #endif</span>
</code></pre>
</div>
<p>ส่วนเวลาเรียกใช้คำสั่ง เราสามารถเขียนโค้ดต่อไปนี้ได้</p>
<div class='highlight'>
<pre><code class='c'> <span class='kt'>char</span> <span class='o'>*</span><span class='n'>buffer</span><span class='p'>;</span>
<span class='cp'> #ifdef _WIN32</span>
 <span class='n'>buffer</span> <span class='o'>=</span> <span class='n'>_getcwd</span><span class='p'>(</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='mi'>0</span><span class='p'>);</span>
<span class='cp'> #else</span>
 <span class='n'>buffer</span> <span class='o'>=</span> <span class='n'>getcwd</span><span class='p'>(</span><span class='nb'>NULL</span><span class='p'>,</span> <span class='mi'>0</span><span class='p'>);</span>
<span class='cp'> #endif</span>
</code></pre>
</div>
<h3 id='id2'>เครื่องมือและสภาพแวดล้อมที่แตกต่าง</h3>
<p>อย่างไรก็ดีการเขียน preprocessor macro ก็ยังไม่สามารถแก้ปัญหาได้ทั้งหมด เนื่องจากคอมไพเลอร์ของแต่ละแพลตฟอร์มมีวิธีการเรียกใช้และการกำหนดออปชันที่แตกต่างกัน นอกจากนี้ การคอมไพล์โปรแกรมภาษา C++ เป็นกระบวนการที่ซับซ้อน ดังนั้นแพลตฟอร์มต่างๆ จึงมีเครื่องมือสำหรับกำหนดกระบวนการนี้เป็นของตัวเอง</p>
<p>ถึงแม้ว่าในปัจจุบัน <a href='http://en.wikipedia.org/wiki/Make_%28software%29'><code>make</code></a> จะเป็นเครื่องมือมาตรฐานสำหรับการสร้างซอฟต์แวร์ภาษา C++ ในแพลตฟอร์มที่สืบเชื้อสายมาจาก Unix ทั้งหลาย นอกจากนี้ใน Windows มี <a href='http://msdn.microsoft.com/en-us/library/ms930369.aspx'><code>nmake</code></a> ให้ใช้ด้วย อย่างไรก็ดีการใช้ <code>make</code> ทำให้โปรแกรมเมอร์ต้องสละความสะดวกสบายของ IDE ที่ตนถนัด (เนื่องจากผู้เขียนใช้งาน Visual C++ จนติด การต้องไปเขียน Makefile เองจึงเป็นเรื่องที่ทรมานยิ่ง)</p>
<p>แต่ปัญหาที่ใหญ่ที่สุดเกิดขึ้นเมื่อซอฟต์แวร์ที่เราสร้างใช้ไลบรารีภายนอกที่เราไม่ได้เขียนเอง เนื่องจากแพลตฟอร์มต่างๆ มีที่เก็บไลบรารีที่แตกต่างกัน เช่น ใน Mac จะเก็บอยู่ในไดเรคทอรี <code>/Library</code> ส่วนใน Unix อาจเก็บอยู่ที่ <code>/usr</code> หรือ <code>/usr/local</code> ส่วนใน Windows นั้นไม่มีที่เก็บที่แน่นอน เป็นเรื่องของโปรแกรมเมอร์ที่จะต้องรู้ที่เก็บไลบรารีเอง</p>
<p>ในแพลตฟอร์ม Unix มีชุดของเครื่องมือที่เรียกว่า <a href='http://en.wikipedia.org/wiki/Autotools'><code>Autotools</code></a> ซึ่งสามารถตรวจว่าระบบที่จะทำการคอมไพล์ไฟล์มีไลบรารีที่ต้องการให้ใช้หรือไม่ รวมทั้งสร้างไฟล์ชื่อ <code>config.h</code> ซึ่งมี preprocessor macro ซึ่งช่วยให้เรา include ไฟล์และเลือกใช้คำสั่งที่ถูกต้องได้ดังที่กล่าวไว้ข้างบน แต่การใช้ Autotools บังคับให้เราต้องใช้ <code>make</code> ไปโดยปริยาย</p>
<p>ดังนั้นจึงการดีอย่างยิ่งหากเรามีเครื่องมือที่ช่วยให้เรากำหนดซอฟต์แวร์ที่เราต้องการสร้างเพียงครั้งเดียว (ขั้นนี้เรียกว่าการทำ software project configuration และเพื่อความง่ายเราจะแทน &#8220;ซอฟต์แวร์ที่จะสร้าง&#8221; ด้วยคำว่า &#8220;โปรเจค&#8221; แทน) แล้วอนุญาตให้เราสามารถคอมไพล์ซอฟต์แวร์นี้ด้วยเครื่องมืออะไรก็ได้ที่เราถนัดบนแพลตฟอร์มที่เราถนัด แต่ในขณะเดียวกันเราก็ยังสามารถพัฒนาซอฟต์แวร์เดียวกันนี้บนแพลตฟอร์มอื่นได้ด้วย</p>
<h2 id='cmake'>CMake</h2>
<p>CMake เป็นเครื่องมือที่ช่วยตอบสนองความต้องการข้างต้นได้ จากมุมมองของผู้ใช้ CMake แล้วกระบวนการคอมไพล์โปรแกรมสามารถแยกออกเป็นสามขั้นตอนดังต่อไปนี้</p>
<ol>
<li>
<p>เขียนไฟล์ชื่อ <code>CMakeLists.txt</code> เพื่อกำหนดโปรเจค</p>
</li>
<li>
<p>รัน CMake เพื่อสร้าง build script ที่เฉพาะเจาะจงกับแพลตฟอร์มและเครื่องมือที่เราใชัพัฒนาโปรแกรม</p>
</li>
<li>
<p>build โปรแกรมด้วยเครื่องมือดังกล่าว</p>
</li>
</ol>
<p>สังเกตว่าหน้าที่ของ CMake คือการอ่านพิมพ์เขียวของโปรเจคจากไฟล์ <code>CMakeLists.txt</code> แล้วสร้าง build script แต่มันไม่ได้ทำการ build โปรแกรมด้วยตัวเองเหมือนกับเครื่องมือลักษณะคล้ายๆ กันตัวอื่น นี่เป็นสาเหตุที่ทำให้เราสามารถใช้เครื่องมืออะไรก็ได้ที่ CMake สนับสนุนในการพัฒนาโปรแกรมตามความถนัดของเรา</p>
<h2 id='_cmake'>การติดตั้ง CMake</h2>
<p>คุณสามารถดาวน์โหลด CMake จาก<a href='http://www.cmake.org/cmake/resources/software.html'>หน้าดาวน์โหลดของเวบไซต์อย่างเป็นทางการ</a> โดยเลือก installer ที่เหมาะสมกับแพลตฟอร์มที่คุณใช้</p>
<p>ผู้ใช้ Debian หรือ Ubuntu สามารถติดตั้ง CMake ผ่าน <code>apt-get</code> ได้ด้วยการสั่ง</p>
<pre><code>&gt; sudo apt-get cmake</code></pre>
<p>ส่วนผู้ใช้ Mac ที่ใช้ <a href='http://www.macports.org/'>MacPorts</a> สามารถติดตั้งได้โดยการสั่ง</p>
<pre><code>&gt; sudo port install cmake</code></pre>
<p>หลังจากติดตั้งแล้วเราสามารถทดสอบว่า CMake ถูกติดตั้งเรียบร้อยดีหรือไม่ด้วยการสั่ง</p>
<pre><code>&gt; cmake</code></pre>
<p>ใน command prompt ซึ่งหลังจากสั่งแล้วคุณควรจะพบว่า CMake พิมพ์วิธีการใช้มันอย่างคร่าวๆ รวมทั้งออปชันต่างๆ ที่คุณสามารถกำหนดได้ออกมาทางหน้าจอ โดยตอนท้ายของข้อความที่ CMake พิมพ์ออกมาจะมีส่วนที่กล่าวถึง &#8220;Generators&#8221; ซึ่งบอกว่าขณะนี้ CMake สามารถสร้าง build script ที่ใช้กับเครื่องมือใดได้บ้าง</p>
<p>เมื่อผู้เขียนรันคำสั่ง <code>cmake</code> บนภายใต้ระบบปฏิบัติการ Mac OSX แล้วได้ผลลัพธ์ดังต่อไปนี้</p>
<pre><code>cmake version 2.6-patch 4
Usage

  cmake [options] &lt;path-to-source&gt;
  cmake [options] &lt;path-to-existing-build&gt;

Options
  &lt;&lt;&lt; ข้อความแสดงออปชันต่างๆ ที่ผู้ใช้สามารถกำหนดได้ &gt;&gt;&gt;

Generators

The following generators are available on this platform:
  Unix Makefiles              = Generates standard UNIX makefiles.
  Xcode                       = Generate XCode project files.
  CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
  Eclipse CDT4 - Unix Makefiles
                              = Generates Eclipse CDT 4.0 project files.
  KDevelop3                   = Generates KDevelop 3 project files.
  KDevelop3 - Unix Makefiles  = Generates KDevelop 3 project files.</code></pre>
<p>แต่ถ้ารันมันภายใต้ Windows XP แล้วจะได้ผลลัพธ์ดังต่อไปนี้</p>
<pre><code>cmake version 2.8.1
Usage

  cmake [options] &lt;path-to-source&gt;
  cmake [options] &lt;path-to-existing-build&gt;

Options
  &lt;&lt;&lt; ข้อความแสดงออปชันต่างๆ ที่ผู้ใช้สามารถกำหนดได้ &gt;&gt;&gt;

Generators

The following generators are available on this platform:
  Borland Makefiles           = Generates Borland makefiles.
  MSYS Makefiles              = Generates MSYS makefiles.
  MinGW Makefiles             = Generates a make file for use with
                                mingw32-make.
  NMake Makefiles             = Generates NMake makefiles.
  NMake Makefiles JOM         = Generates JOM makefiles.
  Unix Makefiles              = Generates standard UNIX makefiles.
  Visual Studio 10            = Generates Visual Studio 10 project files.
  Visual Studio 10 Win64      = Generates Visual Studio 10 Win64 project
                                files.
  Visual Studio 6             = Generates Visual Studio 6 project files.
  Visual Studio 7             = Generates Visual Studio .NET 2002 project
                                files.
  Visual Studio 7 .NET 2003   = Generates Visual Studio .NET 2003 project
                                files.
  Visual Studio 8 2005        = Generates Visual Studio .NET 2005 project
                                files.
  Visual Studio 8 2005 Win64  = Generates Visual Studio .NET 2005 Win64
                                project files.
  Visual Studio 9 2008        = Generates Visual Studio 9 2008 project files.
  Visual Studio 9 2008 Win64  = Generates Visual Studio 9 2008 Win64 project
                                files.
  Watcom WMake                = Generates Watcom WMake makefiles.
  CodeBlocks - MinGW Makefiles= Generates CodeBlocks project files.
  CodeBlocks - NMake Makefiles= Generates CodeBlocks project files.
  CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
  Eclipse CDT4 - MinGW Makefiles
                              = Generates Eclipse CDT 4.0 project files.
  Eclipse CDT4 - NMake Makefiles
                              = Generates Eclipse CDT 4.0 project files.
  Eclipse CDT4 - Unix Makefiles
                              = Generates Eclipse CDT 4.0 project files.</code></pre>
<p>ผลลัพธ์ทั้งสองแสดงให้เห็นว่าเราสามารถสร้าง build script สำหรับเครื่องมือที่แตกต่างกันได้หลายชนิด และ CMake ยังรู้ด้วยว่าในแพลตฟอร์มต่างๆ กันมีเครื่องมือที่แตกต่างกัน</p>
<h2 id='hello_world__cmake'>Hello World ด้วย CMake</h2>
<p>ในส่วนนี้เราจะทำการสร้างโปรแกรมที่ง่ายที่สุดด้วย CMake ก่อนอื่นให้คุณสร้างไดเรคทอรีชื่อ <code>helloworld</code> ซึ่งมีโครงสร้างดังต่อไปนี้</p>
<pre><code>helloworld/
    CMakeLists.txt
    main.cpp</code></pre>
<p>โดยที่ <code>main.cpp</code> มีเนื้อหาตามธรรมเนียมดังนี้</p>
<div class='highlight'>
<pre><code class='c'><span class='cp'> #include &lt;stdio.h&gt;</span>

 <span class='kt'>int</span> <span class='nf'>main</span><span class='p'>()</span>
 <span class='p'>{</span>
   <span class='n'>printf</span><span class='p'>(</span><span class='s'>&quot;hello, world</span><span class='se'>\n</span><span class='s'>&quot;</span><span class='p'>);</span>
   <span class='k'>return</span> <span class='mi'>0</span><span class='p'>;</span>
 <span class='p'>}</span>
</code></pre>
</div>
<p>ไฟล์ <code>CMakeLists.txt</code> เป็นพิมพ์เขียวของโปรเจค ซึ่งในกรณีนี้มันมีเนื้อหาดังต่อไปนี้</p>
<pre><code>PROJECT(sample)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_EXECUTABLE(helloworld main.cpp)</code></pre>
<p>บรรทัดแรกของไฟล์บอกว่าโปรเจคของเรามีชื่อว่า sample ส่วนบรรทัดที่สองเป็นการเช็คว่า CMake ที่เราใช้นั้นใหม่กว่าเวอร์ชัน 2.6 บรรทัดที่สามเป็นบรรทัดบอกว่าเราจะทำการสร้างไฟล์ executable เพียงไฟล์เดียวชื่อ <code>helloworld</code> ด้วยการคอมไพล์ <code>main.cpp</code></p>
<p>ตอนนี้เราพร้อมที่จะสร้าง build script ด้วย CMake แล้ว อันดับแรกให้ทำการเปลี่ยนไดเรคทอรีไปยังไดเรคทอรี <code>helloworld</code> ที่เราเพิ่งจะสร้างขึ้น</p>
<pre><code>&gt; cd helloworld</code></pre>
<p>แล้วจึงสั่ง</p>
<pre><code>&gt; cmake .</code></pre>
<p>เพื่อบอกให้ CMake สร้าง build script โดยอ่าน <code>CMakeLists.txt</code> จากไดเรคทอรีปัจจุบัน การสั่งแบบนี้สอดคล้องกับการใช้ CMake โดยสั่ง</p>
<pre><code>cmake [options] &lt;path-to-source&gt;</code></pre>
<p>ที่เราเคยเห็นแล้วจากการสั่ง <code>cmake</code> เปล่าๆ ข้างบน</p>
<h3 id='id3'>ผลลัพธ์</h3>
<p>เนื่องจากเราไม่ได้กำหนดว่าจะให้ CMake ใช้ generator ตัวใด CMake จึงเลือกใช้ generator ตัวที่ถูกเลือกเป็นตัวเลือกอัตโนมัติสำหรับแพลตฟอร์มที่เรารันมัน</p>
<p>เวลาที่ผู้เขียนใช้ Mac ผู้เขียนพบว่า CMake จะสร้าง &#8220;Unix Makefiles&#8221; ดังนั้นหากเราดูไฟล์ในไดเรคทอรี helloworld หล้งรัน CMake จะมีไฟล์ดังต่อไปนี้</p>
<pre><code>&gt; ls
CMakeCache.txt     Makefile                main.cpp
CMakeFiles         cmake_install.cmake
CMakeLists.txt</code></pre>
<p>โดยไฟล์ที่เป็นผลลัพธ์ที่สำคัญที่สุดคือ <code>Makefile</code> ซึ่งทำให้เราสามารถสั่ง</p>
<pre><code>&gt; make</code></pre>
<p>แล้วจะได้ไฟล์ executable ชื่อ <code>helloworld</code> ตามที่เราต้องการ</p>
<p>ในทางกลับกัน ถ้าผู้เขียนใช้ Windows แล้ว CMake จะใช้ generator ชื่อ &#8220;Visual Studio 9 2008&#8221; เพื่อสร้างไฟล์โปรเจคสำหรับ Visual C++ 2008 เมื่อผู้เขียนสำรวจดูไดเรคทอรี <code>helloworld</code> ก็พบว่ามีไฟล์ดังต่อไปนี้</p>
<pre><code>C:\***\helloworld&gt;dir
 Volume in drive C is ********
 Volume Serial Number is ****-****

 Directory of C:\***\helloworld

05/08/2010  08:00 PM    &lt;DIR&gt;          .
05/08/2010  08:00 PM    &lt;DIR&gt;          ..
05/08/2010  08:00 PM            23,520 ALL_BUILD.vcproj
05/08/2010  08:00 PM            12,587 CMakeCache.txt
05/08/2010  08:00 PM    &lt;DIR&gt;          CMakeFiles
05/08/2010  07:57 PM                91 CMakeLists.txt
05/08/2010  08:00 PM             1,473 cmake_install.cmake
05/08/2010  08:00 PM            26,038 helloworld.vcproj
05/08/2010  07:56 PM                92 main.cpp
05/08/2010  08:00 PM             3,151 sample.sln
05/08/2010  08:00 PM            20,415 ZERO_CHECK.vcproj
               8 File(s)         87,367 bytes
               3 Dir(s)   5,633,990,656 bytes free</code></pre>
<p>ซึ่งผู้เขียนสามารถใช้ Microsoft Visual Studio 2009 เปิดไฟล์ <code>sample.sln</code> เพื่อคอมไพล์ <code>main.cpp</code> ให้กลายเป็น <code>helloworld.exe</code> ได้</p>
<h3 id='_generator_'>เลือก Generator เอง</h3>
<p>เราสามารถกำหนดให้ CMake ใช้ generator ตัวอื่นๆ ที่ไม่ใช้ตัวที่มันเลือกให้อัตโนมัติได้ ด้วยการใช้ออปชัน <code>-G &quot;ชื่อ generator&quot;</code> ยกตัวอย่างเช่น หากเราต้องการใช้ Xcode ในการพัฒนาซอฟต์แวร์บนเครื่อง Mac แทนที่จะใช้ Unix Makefiles เราสามารถสั่ง</p>
<pre><code>&gt; cmake -G &quot;Xcode&quot; .</code></pre>
<p>แทนการสั่ง <code>cmake .</code> ที่กล่าวไปในส่วนที่แล้ว ในกรณีของโปรเจค <code>sample</code> ข้างบน เราได้จะได้ไดเรคทอรีชื่อ <code>sample.xcodeproj</code> ซึ่งสามารถใช้ Xcode เปิดได้</p>
<p>คุณสามารถชื่อของ generator ที่ใช้ได้ในแต่ละแพลตฟอร์มได้จากส่วน &#8220;Generators&#8221; ของข้อความที่ CMake พิมพ์ออกมาเมื่อเราสั่ง <code>cmake</code> เฉยๆ ใน command prompt</p>
<p>อย่างไรก็ดี หากคุณใช้สั่ง <code>cmake .</code> สร้าง build script ลงในไดเรคทอรี <code>helloworld</code> เสร็จแล้วพยายามจะเปลี่ยน generator ที่ใช้ด้วยการสั่ง <code>cmake -G &quot;Xcode&quot; .</code> แล้ว CMake จะบ่นว่า</p>
<pre><code>CMake Error: Error: generator : Xcode
Does not match the generator used previously: Unix Makefiles
Either remove the CMakeCache.txt file or choose a different binary directory</code></pre>
<p>ปัญหานี้เกิดขึ้นจากข้อจำกัดของ CMake ที่ว่า ในไดเรคทอรีหนึ่งๆ มันสามารถสร้าง build script ของเครื่องมือได้เพียงเครื่องมือเดียวเท่านั้น หากเราต้องการเปลี่ยนเครื่องมือใหม่ เราจะต้องทำให้ CMake &#8220;ลืม&#8221; build script ของเครื่องมือเดิมด้วยการลบไฟล์ <code>CMakeCache.txt</code> แล้วจึงสั่ง <code>cmake -G &quot;Xcode&quot; .</code> ใหม่อีกรอบ หรือไม่ก็ไปสร้าง build script ในไดเรคทอรีใหม่เลย</p>
<h2 id='insource_build__outofsource_build'>In-Source Build และ Out-of-Source Build</h2>
<p>สังเกตว่าในการ build โปรเจค <code>sample</code> ในส่วนที่แล้วนั้น ได้เรคทอรี <code>helloworld</code> บรรจุดทั้งซอร์สโค้ด (มีสองไฟล์คือ <code>main.cpp</code> และ <code>CMakeLists.txt</code>) และไฟล์อื่นๆ ที่ CMake สร้างขึ้นไว้ทั้งคู่ การทำเช่นนี้เรียกว่าการทำ <em>in-source build</em> และมันมีข้อเสียดังต่อไปนี้</p>
<ol>
<li>
<p>ไดเรคทอรีที่เก็บซอร์สโค้ดสามารถเก็บ build script ของเครื่องมือได้เครื่องมือเดียวเท่านั้น จึงเกิดความไม่สะดวกอย่างยิ่งเวลาต้องการสร้าง build script สำหรับเครื่องมือหลายๆ เครื่องมือ</p>
</li>
<li>
<p>ไฟล์ของ CMake ปะปนกับไฟล์ซอร์สโค้ด ทำให้การจัดการซอร์สโค้ดทำได้ยากขึ้น โดยเฉพาะเวลาที่เราเก็บซอร์สโค้ดโดยใช้ซอฟต์แวร์ version control ซึ่งเราจะต้องคอยมาบอกระบุว่าไฟล์ไหนเป็นซอร์สโค้ด (ซึ่งต้องถูกเก็บใน version control) และไฟล์ไหนเป็นไฟล์ที่ CMake สร้างขึ้น (ซึ่งไม่ควรถูกเก็บใน version control)</p>
</li>
</ol>
<p>ในทางกลับกัน <em>out-of-source build</em> คือการแยกไดเรคทอรีที่เก็บซอร์สโค้ด (CMake เรียกไดเรคทอรีนี้ว่า <em>source directory</em>) และไดเรคทอรีที่เก็บ build script และข้อมูลอื่นๆ (CMake เรียกไดเรคทอรีนี้ว่า <em>binary directory</em>) ให้เป็นคนละไดเรคทอรีกัน การทำ out-of-source build ช่วยให้เราหลีกเลี่ยงปัญหาข้างต้นทั้งสองข้อได้โดยสิ้นเชิง โดยแลกมากับการจัดระเบียบวิธีการเก็บไฟล์ใหม่ และการพิมพ์ค่ำสั่งเพิ่มอีกเล็กน้อยตอนเรียก CMake เท่านั้น</p>
<h3 id='id4'>จัดระเบียบไฟล์ใหม่</h3>
<p>เราอาจจัดระเบียบไฟล์เพื่อทำ out-of-source build โดยเอาซอร์สโค้ดทั้งหมดไปใส่ไว้ในไดเรคทอรีชื่อ <code>src</code> ซึ่งทำหน้าที่เป็น source directory และสร้างไดเรคทอรีว่างชื่อ <code>build</code> เพื่อทำหน้าที่เป็น build directory ดังนั้นสำหรับโปรเจค <code>sample</code> เราอาจจัดระเบียบไฟล์ใหม่ดังต่อไปนี้</p>
<pre><code>helloworld/
    build/
    src/
        CMakeLists.txt
        main.cpp</code></pre>
<h3 id='_cmake__build_directory'>เรียก CMake จาก build directory</h3>
<p>หลังจากนั้น เวลาเราจะสร้าง build script ก็ให้เปลี่ยนไดเรคทอรีไปยัง <code>build</code>:</p>
<pre><code>&gt; cd helloworld/build</code></pre>
<p>แล้วจึงสั่ง <code>cmake</code> แล้วให้ source directory เป็น argument:</p>
<pre><code>&gt; cmake ../src</code></pre>
<p>เมื่อสั่งแล้วไฟล์ build script ทุกอย่างจะถูกบรรจุอยุ่ใน <code>build</code> และเมื่อเราเรียก <code>make</code> (สมมติว่าเราเขียนโปรแกรมอยู่บนเครื่อง Mac) แล้วเราจะได้ไฟล์ <code>helloworld</code> อยู่ในไดเรคทอรี <code>build</code> ด้วย</p>
<p>หลังจากที่เราสั่ง <code>cmake</code> โดยให้ source directory เป็น argument ไปเป็นครั้งแรกแล้ว หากเราเข้าไปใน build directory อีกครั้งแล้วสั่ง <code>cmake .</code> อีกครั้ง CMake จะ update ไฟล์ใน build directory ใหม่โดยใช้ generator ตัวเดิม ทำให้เราไม่ต้องพิมพ์ตำแหน่งของ source directory อีกต่อไปเลย ทำให้เกิดความสะดวกขึ้นมาก</p>
<h3 id='_build_script__'>สร้าง build script สำหรับเครื่องมือหลายๆ เครื่องมือ</h3>
<p>เราสามารถมี build directory ได้หลาย build directory ยกตัวอย่างเช่นหากเราต้องการใช้ Xcode ควบคู่ไปกับ Makefile เราอาจสร้างไดเรคทอรี <code>helloworld/build_xcode</code> และ <code>helloworld/build_make</code> สำหรับเป็น build directory ของเครื่องมือทั้งสอง ตามลำดับ</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/278/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=278&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2010/05/08/basic-cmake/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploiting Inter-pixel Coherence II</title>
		<link>http://pramook.wordpress.com/2009/07/17/exploiting-inter-pixel-coherence-ii/</link>
		<comments>http://pramook.wordpress.com/2009/07/17/exploiting-inter-pixel-coherence-ii/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 08:39:51 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[computer graphics]]></category>
		<category><![CDATA[adaptive sampling]]></category>
		<category><![CDATA[compressive sensing]]></category>
		<category><![CDATA[light transport]]></category>
		<category><![CDATA[wavelet]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=165</guid>
		<description><![CDATA[Let&#8217;s come back to the discussion on compressive sensing applied to light transport problem. We will talk about two approaches to exploit inter-pixel coherence today. The first is described to in the paper Compressive Light Transport Sensing by Peers et &#8230; <a href="http://pramook.wordpress.com/2009/07/17/exploiting-inter-pixel-coherence-ii/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=165&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s come back to the discussion on compressive sensing applied to light transport problem. We will talk about two approaches to exploit inter-pixel coherence today. </p>
<ul>
<li>The first is described to in the paper <em>Compressive Light Transport Sensing</em> by Peers et al. (<a href="http://www1.cs.columbia.edu/~dhruv/transportacquisition/clts.pdf">Link</a>)</li>
<li>The second is a recent technical report(?) titled <em>Adaptive compressed image sensing based on wavelet modeling and direct sampling</em> by Deutsch, Averbuch, and Dekel. (<a href="http://shaidekel.tripod.com/ADS.pdf">Link</a>)</li>
</ul>
<p>What these two approaches have in common is their use of hierarchical basis, wavelets in particular. Computation in both papers proceeds from one involving coarse wavelet coefficients to one involving finer coefficients, and the result of the coarser level is used to &#8220;bootstrap&#8221; the computation of the finer level.<span id="more-165"></span></p>
<h3>Computing Coherent Transfer Functions</h3>
<p>Recall the light transport equation:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=C%5ET+%3D+%28L%5ET+B%29+%5Chat+T.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T = (L^T B) &#92;hat T.' title='C^T = (L^T B) &#92;hat T.' class='latex' /></p>
<p>Each column of <img src='http://s0.wp.com/latex.php?latex=C%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T' title='C^T' class='latex' /> corresponds the colors of a pixel under different lighting configuration. Thus, we have <img src='http://s0.wp.com/latex.php?latex=p&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='p' title='p' class='latex' /> independent equations of the form:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bc%7D%5ET_k+%3D+%28L%5ET+B%29+%5Chat%7B%5Cmathrm%7Bt%7D%7D_k.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{c}^T_k = (L^T B) &#92;hat{&#92;mathrm{t}}_k.' title='&#92;mathbf{c}^T_k = (L^T B) &#92;hat{&#92;mathrm{t}}_k.' class='latex' /></p>
<p>Each equation can be solved with a decoding algorithm to yield transfer vector <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathrm+t%7D_k&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathrm t}_k' title='&#92;hat{&#92;mathrm t}_k' class='latex' /> for each pixel. However, solving these equations independently leads to noisy transfer functions.</p>
<p>To solve the above problem, the paper makes use of the Haar <em>scaling functions</em>. (The paper said they used the Haar wavelet basis. This is misleading. What they actually use are the scaling functions.) </p>
<h5>Haar Scaling Functions</h5>
<p>Let us define the Haar scaling functions. Suppose we have a <img src='http://s0.wp.com/latex.php?latex=2%5EJ+%5Ctimes+2%5EJ&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^J &#92;times 2^J' title='2^J &#92;times 2^J' class='latex' /> image. We can view this image as a <img src='http://s0.wp.com/latex.php?latex=2%5EJ+%5Ctimes+2%5EJ&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^J &#92;times 2^J' title='2^J &#92;times 2^J' class='latex' /> matrix <img src='http://s0.wp.com/latex.php?latex=A&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A' title='A' class='latex' />. A Haar scaling function is a function from the matrix indices set <img src='http://s0.wp.com/latex.php?latex=2%5EJ+%5Ctimes+2%5EJ&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^J &#92;times 2^J' title='2^J &#92;times 2^J' class='latex' /> to a real number (i.e., a color), which basically means that it&#8217;s actually an image. </p>
<p>The Haar scaling functions are split into <img src='http://s0.wp.com/latex.php?latex=J%2B1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='J+1' title='J+1' class='latex' /> levels from Level <img src='http://s0.wp.com/latex.php?latex=0&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='0' title='0' class='latex' /> to Level <img src='http://s0.wp.com/latex.php?latex=J&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='J' title='J' class='latex' />. At a particular level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' />, there are <img src='http://s0.wp.com/latex.php?latex=2%5E%7B2j%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{2j}' title='2^{2j}' class='latex' /> scaling functions, and each is denoted by <img src='http://s0.wp.com/latex.php?latex=%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;varphi^{(j)}_{k&#92;ell}' title='&#92;varphi^{(j)}_{k&#92;ell}' class='latex' /> where <img src='http://s0.wp.com/latex.php?latex=0+%5Cleq+m%2C+n+%5Cleq+2%5Ej-1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='0 &#92;leq m, n &#92;leq 2^j-1' title='0 &#92;leq m, n &#92;leq 2^j-1' class='latex' />. At level <img src='http://s0.wp.com/latex.php?latex=J&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='J' title='J' class='latex' />, each scaling function <img src='http://s0.wp.com/latex.php?latex=%5Cvarphi%5E%7B%28J%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;varphi^{(J)}_{k&#92;ell}' title='&#92;varphi^{(J)}_{k&#92;ell}' class='latex' /> is the sampling of Pixel <img src='http://s0.wp.com/latex.php?latex=%28k%2C%5Cell%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(k,&#92;ell)' title='(k,&#92;ell)' class='latex' />. That is, </p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Cvarphi%5E%7B%28J%29%7D_%7Bk%5Cell%7D%28k%27%2C+%5Cell%27%29+%3D+%5Cbegin%7Bcases%7D1%2C+%26+k%27+%3D+k%5C+%5Cmathrm%7Band%7D%5C+%5Cell%27+%3D+%5Cell+%5C%5C+0%2C+%26+k%27+%5Cneq+k%5C+%5Cmathrm%7Bor%7D%5C+%5Cell%27+%3D+%5Cell+%5Cend%7Bcases%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle &#92;varphi^{(J)}_{k&#92;ell}(k&#039;, &#92;ell&#039;) = &#92;begin{cases}1, &amp; k&#039; = k&#92; &#92;mathrm{and}&#92; &#92;ell&#039; = &#92;ell &#92;&#92; 0, &amp; k&#039; &#92;neq k&#92; &#92;mathrm{or}&#92; &#92;ell&#039; = &#92;ell &#92;end{cases}' title='&#92;displaystyle &#92;varphi^{(J)}_{k&#92;ell}(k&#039;, &#92;ell&#039;) = &#92;begin{cases}1, &amp; k&#039; = k&#92; &#92;mathrm{and}&#92; &#92;ell&#039; = &#92;ell &#92;&#92; 0, &amp; k&#039; &#92;neq k&#92; &#92;mathrm{or}&#92; &#92;ell&#039; = &#92;ell &#92;end{cases}' class='latex' />,</p>
<p>making its inner product with the picture equal the value of Pixel <img src='http://s0.wp.com/latex.php?latex=%28k%2C%5Cell%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(k,&#92;ell)' title='(k,&#92;ell)' class='latex' />:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Clangle+%5Cvarphi%5E%7B%28J%29%7D_%7Bk+%5Cell%7D%2C+A+%5Crangle+%3D+a_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle &#92;langle &#92;varphi^{(J)}_{k &#92;ell}, A &#92;rangle = a_{k&#92;ell}' title='&#92;displaystyle &#92;langle &#92;varphi^{(J)}_{k &#92;ell}, A &#92;rangle = a_{k&#92;ell}' class='latex' />.</p>
<p>Scaling functions at level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' /> are defined recursively from those at level <img src='http://s0.wp.com/latex.php?latex=j%2B1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j+1' title='j+1' class='latex' /> as follows:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%2C+%5Cell%7D+%3D+%5Cfrac%7B1%7D%7B2%7D%5Cbigg%28%5Cvarphi%5E%7B%28j%2B1%29%7D_%7B2k%2C+2%5Cell%7D+%2B++%5Cvarphi%5E%7B%28j%2B1%29%7D_%7B2k%2C+2%5Cell%2B1%7D+%2B+%5Cvarphi%5E%7B%28j%2B1%29%7D_%7B2k%2B1%2C+2%5Cell%7D+%2B+%5Cvarphi%5E%7B%28j%2B1%29%7D_%7B2k%2B1%2C+2%5Cell%2B1%7D%5Cbigg%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle &#92;varphi^{(j)}_{k, &#92;ell} = &#92;frac{1}{2}&#92;bigg(&#92;varphi^{(j+1)}_{2k, 2&#92;ell} +  &#92;varphi^{(j+1)}_{2k, 2&#92;ell+1} + &#92;varphi^{(j+1)}_{2k+1, 2&#92;ell} + &#92;varphi^{(j+1)}_{2k+1, 2&#92;ell+1}&#92;bigg)' title='&#92;displaystyle &#92;varphi^{(j)}_{k, &#92;ell} = &#92;frac{1}{2}&#92;bigg(&#92;varphi^{(j+1)}_{2k, 2&#92;ell} +  &#92;varphi^{(j+1)}_{2k, 2&#92;ell+1} + &#92;varphi^{(j+1)}_{2k+1, 2&#92;ell} + &#92;varphi^{(j+1)}_{2k+1, 2&#92;ell+1}&#92;bigg)' class='latex' />.</p>
<p>We can deduce from this definition that</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D%28k%27%2C+%5Cell%27%29+%3D+%5Cbegin%7Bcases%7D+%5Cfrac%7B1%7D%7B2%5E%7BJ-j%7D%7D%2C+%26+2%5E%7BJ-j%7Dk+%5Cleq+k%27+%3C+2%5E%7BJ-j%7D%28k%2B1%29%5C+%5Cmathrm%7Band%7D%5C+2%5E%7BJ-j%7D%5Cell+%5Cleq+%5Cell+%3C+2%5E%7BJ-j%7D%28%5Cell%2B1%29+%5C%5C+0%2C+%26+%5Cmathrm%7Botherwise%7D%5Cend%7Bcases%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle &#92;varphi^{(j)}_{k&#92;ell}(k&#039;, &#92;ell&#039;) = &#92;begin{cases} &#92;frac{1}{2^{J-j}}, &amp; 2^{J-j}k &#92;leq k&#039; &lt; 2^{J-j}(k+1)&#92; &#92;mathrm{and}&#92; 2^{J-j}&#92;ell &#92;leq &#92;ell &lt; 2^{J-j}(&#92;ell+1) &#92;&#92; 0, &amp; &#92;mathrm{otherwise}&#92;end{cases}' title='&#92;displaystyle &#92;varphi^{(j)}_{k&#92;ell}(k&#039;, &#92;ell&#039;) = &#92;begin{cases} &#92;frac{1}{2^{J-j}}, &amp; 2^{J-j}k &#92;leq k&#039; &lt; 2^{J-j}(k+1)&#92; &#92;mathrm{and}&#92; 2^{J-j}&#92;ell &#92;leq &#92;ell &lt; 2^{J-j}(&#92;ell+1) &#92;&#92; 0, &amp; &#92;mathrm{otherwise}&#92;end{cases}' class='latex' />.</p>
<p>That is, it is a picture of a <img src='http://s0.wp.com/latex.php?latex=2%5E%7BJ-j%7D+%5Ctimes+2%5E%7BJ-j%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{J-j} &#92;times 2^{J-j}' title='2^{J-j} &#92;times 2^{J-j}' class='latex' /> rectangle where the pixel values are <img src='http://s0.wp.com/latex.php?latex=1%2F2%5E%7BJ-j%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='1/2^{J-j}' title='1/2^{J-j}' class='latex' />. The inner product between <img src='http://s0.wp.com/latex.php?latex=%5Cvarphi_%7Bj%2C+k%2C+%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;varphi_{j, k, &#92;ell}' title='&#92;varphi_{j, k, &#92;ell}' class='latex' /> and the image is:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Clangle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D%2C+A+%5Crangle+%3D+%5Cfrac%7B1%7D%7B2%5E%7BJ-j%7D%7D+%5Csum_%7Bk%27+%3D+2%5E%7BJ-j%7Dk%7D%5E%7B+2%5E%7BJ-j%7D%28k%2B1%29-1%7D+%5Csum_%7B%5Cell%27+%3D+2%5E%7BJ-j%7D%5Cell%7D%5E%7B2%5E%7BJ-j%7D%28%5Cell%2B1%29-1%7D+a_%7Bk%27+%5Cell%27%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle &#92;langle &#92;varphi^{(j)}_{k&#92;ell}, A &#92;rangle = &#92;frac{1}{2^{J-j}} &#92;sum_{k&#039; = 2^{J-j}k}^{ 2^{J-j}(k+1)-1} &#92;sum_{&#92;ell&#039; = 2^{J-j}&#92;ell}^{2^{J-j}(&#92;ell+1)-1} a_{k&#039; &#92;ell&#039;}' title='&#92;displaystyle &#92;langle &#92;varphi^{(j)}_{k&#92;ell}, A &#92;rangle = &#92;frac{1}{2^{J-j}} &#92;sum_{k&#039; = 2^{J-j}k}^{ 2^{J-j}(k+1)-1} &#92;sum_{&#92;ell&#039; = 2^{J-j}&#92;ell}^{2^{J-j}(&#92;ell+1)-1} a_{k&#039; &#92;ell&#039;}' class='latex' />,</p>
<p>which is the sum of all pixels in the support of <img src='http://s0.wp.com/latex.php?latex=%5Cvarphi_%7Bj%2Ck%2C%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;varphi_{j,k,&#92;ell}' title='&#92;varphi_{j,k,&#92;ell}' class='latex' /> divided by <img src='http://s0.wp.com/latex.php?latex=2%5E%7BJ-j%7D.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{J-j}.' title='2^{J-j}.' class='latex' /> Thus, <img src='http://s0.wp.com/latex.php?latex=%5Clangle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D%2C+A+%5Crangle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;langle &#92;varphi^{(j)}_{k&#92;ell}, A &#92;rangle &#92;varphi^{(j)}_{k&#92;ell}' title='&#92;langle &#92;varphi^{(j)}_{k&#92;ell}, A &#92;rangle &#92;varphi^{(j)}_{k&#92;ell}' class='latex' /> is a picture of a <img src='http://s0.wp.com/latex.php?latex=2%5E%7BJ-j%7D+%5Ctimes+2%5E%7BJ-j%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{J-j} &#92;times 2^{J-j}' title='2^{J-j} &#92;times 2^{J-j}' class='latex' /> rectangle whose color is the average of the pixels in the support of <img src='http://s0.wp.com/latex.php?latex=%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;varphi^{(j)}_{k&#92;ell}' title='&#92;varphi^{(j)}_{k&#92;ell}' class='latex' />. The projection of <img src='http://s0.wp.com/latex.php?latex=C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C' title='C' class='latex' /> into the space spanned by scaling functions at level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' />, denoted by </p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=A%5E%7B%28j%29%7D+%3D+%5Csum_%7Bk%3D0%7D%5E%7B2%5Ej-1%7D+%5Csum_%7B%5Cell%3D0%7D%5E%7B2%5Ej-1%7D+%5Clangle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D%2C+A+%5Crangle+%5Cvarphi%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A^{(j)} = &#92;sum_{k=0}^{2^j-1} &#92;sum_{&#92;ell=0}^{2^j-1} &#92;langle &#92;varphi^{(j)}_{k&#92;ell}, A &#92;rangle &#92;varphi^{(j)}_{k&#92;ell}' title='A^{(j)} = &#92;sum_{k=0}^{2^j-1} &#92;sum_{&#92;ell=0}^{2^j-1} &#92;langle &#92;varphi^{(j)}_{k&#92;ell}, A &#92;rangle &#92;varphi^{(j)}_{k&#92;ell}' class='latex' />,</p>
<p> can be thought of the original image partitioned into <img src='http://s0.wp.com/latex.php?latex=2%5Ej+%5Ctimes+2%5Ej&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^j &#92;times 2^j' title='2^j &#92;times 2^j' class='latex' /> equally-sized grid. Each grid square&#8217;s color is the average of the color of the pixels covered by the square. </p>
<p>The image <img src='http://s0.wp.com/latex.php?latex=A%5E%7B%280%29%7D%2C+A%5E%7B%281%29%7D%2C+A%5E%7B%282%29%7D%2C+%5Cdotsc%2C+A%5E%7B%28J%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A^{(0)}, A^{(1)}, A^{(2)}, &#92;dotsc, A^{(J)}' title='A^{(0)}, A^{(1)}, A^{(2)}, &#92;dotsc, A^{(J)}' class='latex' /> are approximations of <img src='http://s0.wp.com/latex.php?latex=A&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A' title='A' class='latex' /> from coarse to fine, with  <img src='http://s0.wp.com/latex.php?latex=A%5E%7B%28J%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A^{(J)}' title='A^{(J)}' class='latex' /> being the image <img src='http://s0.wp.com/latex.php?latex=A&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A' title='A' class='latex' /> itself.</p>
<h5>Hierarchical Compressive Sensing</h5>
<p>From this point forward, we will index a pixel in a picture with two indices instead of one. For example, the vector <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bc%7D_%7Bk%5Cell%7D%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{c}_{k&#92;ell}^T' title='&#92;mathbf{c}_{k&#92;ell}^T' class='latex' /> is an <img src='http://s0.wp.com/latex.php?latex=m&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='m' title='m' class='latex' />-vector whose <img src='http://s0.wp.com/latex.php?latex=m&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='m' title='m' class='latex' /> elements are the color of Pixel <img src='http://s0.wp.com/latex.php?latex=%28k%2C%5Cell%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(k,&#92;ell)' title='(k,&#92;ell)' class='latex' /> under the <img src='http://s0.wp.com/latex.php?latex=m&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='m' title='m' class='latex' /> lighting condition.</p>
<p>Note that, if we project the collection of images <img src='http://s0.wp.com/latex.php?latex=C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C' title='C' class='latex' /> to the space spanned by the scaling functions at level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' />, we would get a collection of coarse approximation images <img src='http://s0.wp.com/latex.php?latex=C%5E%7B%28j%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^{(j)}' title='C^{(j)}' class='latex' />. Since each image in <img src='http://s0.wp.com/latex.php?latex=C%5E%7B%28j%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^{(j)}' title='C^{(j)}' class='latex' /> has at most <img src='http://s0.wp.com/latex.php?latex=2%5E%7B2j%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{2j}' title='2^{2j}' class='latex' /> different colors,  so if we were to solve for the transfer functions in:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%28C%5E%7B%28j%29%7D%29%5ET+%3D+%28L%5ET+B%29+%5Chat+T%5E%7B%28j%29%7D.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(C^{(j)})^T = (L^T B) &#92;hat T^{(j)}.' title='(C^{(j)})^T = (L^T B) &#92;hat T^{(j)}.' class='latex' /></p>
<p>There will be at most <img src='http://s0.wp.com/latex.php?latex=2%5E%7B2j%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{2j}' title='2^{2j}' class='latex' /> different transfer functions. Let us denote them by <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j)}_{k&#92;ell}' title='&#92;hat{&#92;mathbf t}^{(j)}_{k&#92;ell}' class='latex' /> for <img src='http://s0.wp.com/latex.php?latex=0+%5Cleq+k%2C+%5Cell+%3C+2%5Ej&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='0 &#92;leq k, &#92;ell &lt; 2^j' title='0 &#92;leq k, &#92;ell &lt; 2^j' class='latex' />.</p>
<p>Since Level <img src='http://s0.wp.com/latex.php?latex=j%2B1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j+1' title='j+1' class='latex' /> has <img src='http://s0.wp.com/latex.php?latex=2%5E%7B2%28j%2B1%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2^{2(j+1)}' title='2^{2(j+1)}' class='latex' /> functions, a function at Level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' /> can be thought of as a parent of 4 functions at <img src='http://s0.wp.com/latex.php?latex=j%2B1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j+1' title='j+1' class='latex' />. In particular, we can say that <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf%7Bt%7D%7D%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' title='&#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' class='latex' /> is the <em>parent</em> of <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7B2k%2C+2%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k, 2&#92;ell}' title='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k, 2&#92;ell}' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7B2k%2C+2%5Cell%2B1%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k, 2&#92;ell+1}' title='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k, 2&#92;ell+1}' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7B2k%2B1%2C+2%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k+1, 2&#92;ell}' title='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k+1, 2&#92;ell}' class='latex' />, and <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7B2k%2B1%2C+2%5Cell%2B1%7D.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k+1, 2&#92;ell+1}.' title='&#92;hat{&#92;mathbf t}^{(j+1)}_{2k+1, 2&#92;ell+1}.' class='latex' /></p>
<p>Let <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf%7Bt%7D%7D%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' title='&#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' class='latex' /> be the parent of <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7Bk%27+%5Cell%27%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j+1)}_{k&#039; &#92;ell&#039;}' title='&#92;hat{&#92;mathbf t}^{(j+1)}_{k&#039; &#92;ell&#039;}' class='latex' />. Because these two functions are correlated, we expect that there difference <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bd%7D%5E%7B%28j%2B1%29%7D_%7Bk%27+%5Cell%27%7D+%3D+%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7Bk%27+%5Cell%27%7D+-+%5Chat%7B%5Cmathbf%7Bt%7D%7D%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{d}^{(j+1)}_{k&#039; &#92;ell&#039;} = &#92;hat{&#92;mathbf t}^{(j+1)}_{k&#039; &#92;ell&#039;} - &#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' title='&#92;mathbf{d}^{(j+1)}_{k&#039; &#92;ell&#039;} = &#92;hat{&#92;mathbf t}^{(j+1)}_{k&#039; &#92;ell&#039;} - &#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' class='latex' /> should be sparse. Thus, we can find the difference by:</p>
<p style="text-align:center;">minimize <img src='http://s0.wp.com/latex.php?latex=%5C%7C+%5Cmathbf%7Bd%7D%5E%7B%28j%2B1%29%7D_%7Bk%27%5Cell%27%7D+%5C%7C_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;| &#92;mathbf{d}^{(j+1)}_{k&#039;&#92;ell&#039;} &#92;|_1' title='&#92;| &#92;mathbf{d}^{(j+1)}_{k&#039;&#92;ell&#039;} &#92;|_1' class='latex' /> subjected to <img src='http://s0.wp.com/latex.php?latex=%28%5Cmathbf+c%5E%7B%28j%29%7D_%7Bk%5Cell%7D%29%5ET+-+%28%5Cmathbf+c%5E%7B%28j%2B1%29%7D_%7Bk%27%5Cell%27%7D%29%5ET+%3D+%28L%5ET+B%29+%5Cmathbf%7Bd%7D%5E%7B%28j%2B1%29%7D_%7Bk%27%5Cell%27%7D.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(&#92;mathbf c^{(j)}_{k&#92;ell})^T - (&#92;mathbf c^{(j+1)}_{k&#039;&#92;ell&#039;})^T = (L^T B) &#92;mathbf{d}^{(j+1)}_{k&#039;&#92;ell&#039;}.' title='(&#92;mathbf c^{(j)}_{k&#92;ell})^T - (&#92;mathbf c^{(j+1)}_{k&#039;&#92;ell&#039;})^T = (L^T B) &#92;mathbf{d}^{(j+1)}_{k&#039;&#92;ell&#039;}.' class='latex' /></p>
<p>Note that <img src='http://s0.wp.com/latex.php?latex=%28%5Cmathbf+c%5E%7B%28j%29%7D_%7Bk%5Cell%7D%29%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(&#92;mathbf c^{(j)}_{k&#92;ell})^T' title='(&#92;mathbf c^{(j)}_{k&#92;ell})^T' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=%28%5Cmathbf+c%5E%7B%28j%2B1%29%7D_%7Bk%27%5Cell%27%7D%29%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(&#92;mathbf c^{(j+1)}_{k&#039;&#92;ell&#039;})^T' title='(&#92;mathbf c^{(j+1)}_{k&#039;&#92;ell&#039;})^T' class='latex' /> are already available because we have taken all the photographs at the highest resolution, so computing them reduces to computing a wavelet transform and doing some additional work. So, if we have computed <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf%7Bt%7D%7D%5E%7B%28j%29%7D_%7Bk%5Cell%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' title='&#92;hat{&#92;mathbf{t}}^{(j)}_{k&#92;ell}' class='latex' />, then <img src='http://s0.wp.com/latex.php?latex=%5Chat%7B%5Cmathbf+t%7D%5E%7B%28j%2B1%29%7D_%7Bk%27%5Cell%27%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{&#92;mathbf t}^{(j+1)}_{k&#039;&#92;ell&#039;}' title='&#92;hat{&#92;mathbf t}^{(j+1)}_{k&#039;&#92;ell&#039;}' class='latex' /> can be recovered easily.</p>
<p>The paper suggests that we compute the transfer functions level-by-level from Level 0 to Level <img src='http://s0.wp.com/latex.php?latex=J&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='J' title='J' class='latex' />. Going from Level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' /> to <img src='http://s0.wp.com/latex.php?latex=j%2B1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j+1' title='j+1' class='latex' />, we compute the difference of the transfer functions and add them of the the functions at Level <img src='http://s0.wp.com/latex.php?latex=j&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j' title='j' class='latex' />. The advantage of this approach is that, since transfer functions of nearby pixels share ancestors, these functions should be correlated as well. Hence, the functions appear to be less noisy.</p>
<h3>Adaptive Sampling</h3>
<p>Although the second paper mentions compressive sensing, it is not a compressive sensing paper. It is actually about acquiring wavelet coefficients with fewer direct measurements, no non-linear optimization involved.</p>
<p>Let us suppose that there&#8217;s a camera that can capture a user-specified coefficient of the wavelet transform of an image at a time. If only <img src='http://s0.wp.com/latex.php?latex=S&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='S' title='S' class='latex' /> coefficients are not zero, we would only take <img src='http://s0.wp.com/latex.php?latex=S&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='S' title='S' class='latex' /> snapshots if we have an oracle that locates them for us. Of course, we don&#8217;t have such an oracle, but can we reduce the number of measurements anyway?</p>
<p>The second paper describes a heuristic based on Lipschitz smoothness of the image. A wavelet coefficient represents the function well if the function is smooth in its support. One popular notion of smoothness is the Lipschitz continuity defined below:</p>
<blockquote><p>
<strong>Definition:</strong> A function <img src='http://s0.wp.com/latex.php?latex=f%28%5Ccdot%2C+%5Ccdot%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='f(&#92;cdot, &#92;cdot)' title='f(&#92;cdot, &#92;cdot)' class='latex' /> is <em>uniformly Lipschitz continuous of order <img src='http://s0.wp.com/latex.php?latex=%5Calpha&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;alpha' title='&#92;alpha' class='latex' /></em> at point <img src='http://s0.wp.com/latex.php?latex=%28x%2Cy%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(x,y)' title='(x,y)' class='latex' /> if there exists constant <img src='http://s0.wp.com/latex.php?latex=A%2C+%5Cdelta_1%2C+%5Cdelta_2+%3E+0&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A, &#92;delta_1, &#92;delta_2 &gt; 0' title='A, &#92;delta_1, &#92;delta_2 &gt; 0' class='latex' /> such that, for all <img src='http://s0.wp.com/latex.php?latex=%7C%5Cvarepsilon_1%7C+%3C+%5Cdelta_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='|&#92;varepsilon_1| &lt; &#92;delta_1' title='|&#92;varepsilon_1| &lt; &#92;delta_1' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=%7C%5Cvarepsilon_2%7C+%3C+%5Cdelta_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='|&#92;varepsilon_2| &lt; &#92;delta_2' title='|&#92;varepsilon_2| &lt; &#92;delta_2' class='latex' />, we have </p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5C%7C+f%28x_1%2B%5Cvarepsilon_1%2C+x_2%2B%5Cvarepsilon_2%29+-+f%28x%2Cy%29+%5C%7C_2+%5Cleq++A%28%5Cvarepsilon_1%5E2+%2B+%5Cvarepsilon_2%5E2%29%5E%7B%5Calpha%2F2%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;| f(x_1+&#92;varepsilon_1, x_2+&#92;varepsilon_2) - f(x,y) &#92;|_2 &#92;leq  A(&#92;varepsilon_1^2 + &#92;varepsilon_2^2)^{&#92;alpha/2}' title='&#92;| f(x_1+&#92;varepsilon_1, x_2+&#92;varepsilon_2) - f(x,y) &#92;|_2 &#92;leq  A(&#92;varepsilon_1^2 + &#92;varepsilon_2^2)^{&#92;alpha/2}' class='latex' /></p>
</blockquote>
<p>Let <img src='http://s0.wp.com/latex.php?latex=%5Cpsi_%7Bj%2Ck%2Cl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;psi_{j,k,l}' title='&#92;psi_{j,k,l}' class='latex' /> be a 2D wavelet basis function. The paper states that, if <img src='http://s0.wp.com/latex.php?latex=f&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='f' title='f' class='latex' /> is uniformly Lipschitz continuous to order <img src='http://s0.wp.com/latex.php?latex=%5Calpha&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;alpha' title='&#92;alpha' class='latex' /> at all points in the support of <img src='http://s0.wp.com/latex.php?latex=%5Cpsi_%7Bj%2Ck%2Cl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;psi_{j,k,l}' title='&#92;psi_{j,k,l}' class='latex' />, then </p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%7C+%5Cpsi_%7Bj%2Ck%2Cl%7D%5ET+f+%7C+%5Cleq+C+2%5E%7Bj%5Calpha%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle | &#92;psi_{j,k,l}^T f | &#92;leq C 2^{j&#92;alpha}' title='&#92;displaystyle | &#92;psi_{j,k,l}^T f | &#92;leq C 2^{j&#92;alpha}' class='latex' /></p>
<p>for some constant <img src='http://s0.wp.com/latex.php?latex=C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C' title='C' class='latex' />. Taking the logarithm base 2, we have that</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+%5Clog_2+%7C+%5Cpsi_%7Bj%2Ck%2Cl%7D%5ET+f+%7C+%5Cleq+%5Calpha+j+%2B+%5Clog_2+C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle &#92;log_2 | &#92;psi_{j,k,l}^T f | &#92;leq &#92;alpha j + &#92;log_2 C' title='&#92;displaystyle &#92;log_2 | &#92;psi_{j,k,l}^T f | &#92;leq &#92;alpha j + &#92;log_2 C' class='latex' />.</p>
<p>Hence, if we plot <img src='http://s0.wp.com/latex.php?latex=%5Clog_2+%7C+%5Cpsi_%7Bj%2Ck%2Cl%7D%5ET+f+%7C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;log_2 | &#92;psi_{j,k,l}^T f |' title='&#92;log_2 | &#92;psi_{j,k,l}^T f |' class='latex' /> from <img src='http://s0.wp.com/latex.php?latex=j+%3D+0&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j = 0' title='j = 0' class='latex' /> (coarsest level) to some <img src='http://s0.wp.com/latex.php?latex=j+%3D+J&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='j = J' title='j = J' class='latex' />, we can estimate <img src='http://s0.wp.com/latex.php?latex=%5Calpha&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;alpha' title='&#92;alpha' class='latex' /> (this number is called the Lipschitz exponent) by examining the slope of the graph.</p>
<p>The Lipschitz exponent can be though of as a measure of smoothness: a lower exponent means the function is smoother. The paper suggests that we acquire all wavelet coefficients to some fixed scale. Then, we estimate the Lipschitz exponent of each region and choose to acquire more coefficients in areas where the Lipschitz exponents are higher than a certain threshold.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/165/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=165&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2009/07/17/exploiting-inter-pixel-coherence-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>Tensor unfolding with numpy</title>
		<link>http://pramook.wordpress.com/2009/07/14/tensor-unfolding-with-numpy/</link>
		<comments>http://pramook.wordpress.com/2009/07/14/tensor-unfolding-with-numpy/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 20:00:51 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[numpy]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tensor]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=103</guid>
		<description><![CDATA[We switch gear to some easy programming today. Let&#8217;s write a routine to unfold a tensor. We&#8217;ll use numpy to store tensor as it&#8217;s the only linear algebra library that features multi-dimentional array. The Shortest Numpy Tutorial Ever First, to &#8230; <a href="http://pramook.wordpress.com/2009/07/14/tensor-unfolding-with-numpy/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=103&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We switch gear to some easy programming today. Let&#8217;s write a routine to unfold a tensor. We&#8217;ll use <a href="http://numpy.scipy.org/">numpy</a> to store tensor as it&#8217;s the only linear algebra library that features multi-dimentional array.<span id="more-103"></span></p>
<h3>The Shortest Numpy Tutorial Ever</h3>
<p>First, to use numpy, we import it.<br />
<pre class="brush: python;">
&gt;&gt;&gt; import numpy
</pre><br />
A <img src='http://s0.wp.com/latex.php?latex=3+%5Ctimes+2+%5Ctimes+5+%5Ctimes+4&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='3 &#92;times 2 &#92;times 5 &#92;times 4' title='3 &#92;times 2 &#92;times 5 &#92;times 4' class='latex' /> tensor of zeros can be created as follow:<br />
<pre class="brush: python;">
&gt;&gt;&gt; A = numpy.zeros((3,2,5,4))
</pre><br />
Elements can be accessed and assigned in the way it&#8217;s supposed to work:<br />
<pre class="brush: python;">
&gt;&gt;&gt; A[1,1,3,2] = 5.0
&gt;&gt;&gt; print A[1,1,3,2]
5.0
</pre><br />
The only thing to be careful about is that, like in most programming languages, array indices start at zero, not one.<br />
<pre class="brush: python;">
&gt;&gt;&gt; print A[0,0,0,0]
0.0
&gt;&gt;&gt; print A[1,2,3,2]
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
IndexError: index (2) out of range (0&lt;=index&lt;2) in dimension 1
</pre><br />
Actually, the array reference notation we use above is a shorthand of special method <code>__getitem__</code>. The method takes a tuple of indices as input. So, <code>A.__getitem__((1,1,3,2))</code> has the same effect as <code>A[1,1,3,2]</code>.<br />
<pre class="brush: python;">
&gt;&gt;&gt; print A.__getitem__((1,1,3,2))
5.0
</pre><br />
The attribute <code>ndim</code> gives the number of modes (dimension in numpy terminology), and the attribute <code>shape</code> gives a list of number of components in each mode.<br />
<pre class="brush: python;">
&gt;&gt;&gt; A.ndim
4
&gt;&gt;&gt; A.shape
(3, 2, 5, 4)
&gt;&gt;&gt;
</pre></p>
<h3>Tensor Unfolding</h3>
<p>To compute <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D_%7B%28n%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}_{(n)}' title='&#92;mathcal{A}_{(n)}' class='latex' />, we have to know the order of modes from the one whose index varies the slowest to the one whose index varies the fastest. If we unfold along mode <img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' />, then the list of modes in the aforementioned order is: <img src='http://s0.wp.com/latex.php?latex=n%2B1%2C+n%2B2%2C+...%2C+N-1%2C+0%2C+1%2C+2%2C+...%2C+n-1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n+1, n+2, ..., N-1, 0, 1, 2, ..., n-1' title='n+1, n+2, ..., N-1, 0, 1, 2, ..., n-1' class='latex' />. (Remember, <img src='http://s0.wp.com/latex.php?latex=N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='N' title='N' class='latex' /> is the number of modes, and indices start at 0 now that we&#8217;re in the programming world.) Let write a function to create this list. The function can simply concatenate <img src='http://s0.wp.com/latex.php?latex=n%2B1%2C+n%2B2%2C+%5Cdotsc%2C+N-1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n+1, n+2, &#92;dotsc, N-1' title='n+1, n+2, &#92;dotsc, N-1' class='latex' />  with <img src='http://s0.wp.com/latex.php?latex=0%2C+1%2C+%5Cdotsc%2C+n-1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='0, 1, &#92;dotsc, n-1' title='0, 1, &#92;dotsc, n-1' class='latex' /> to get the result.</p>
<p><pre class="brush: python;">
def __get_unfolding_mode_order(A, n):
    return [i for i in xrange(n+1, A.ndim)] + [i for i in xrange(n)]
</pre></p>
<p>The next problem is to figure which element of <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> does the element in Row <img src='http://s0.wp.com/latex.php?latex=r&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='r' title='r' class='latex' /> and Column <img src='http://s0.wp.com/latex.php?latex=c&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='c' title='c' class='latex' /> correspond to. Suppose that it corresponds to <img src='http://s0.wp.com/latex.php?latex=a_%7Bi_1+i_2+%5Cdotsm+i_N%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{i_1 i_2 &#92;dotsm i_N}' title='a_{i_1 i_2 &#92;dotsm i_N}' class='latex' />. We have that <img src='http://s0.wp.com/latex.php?latex=i_n+%3D+r&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_n = r' title='i_n = r' class='latex' />, and we can write <img src='http://s0.wp.com/latex.php?latex=c&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='c' title='c' class='latex' /> in terms of <img src='http://s0.wp.com/latex.php?latex=i_1%2C+i_2%2C+%5Cdotsc%2C+i_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1, i_2, &#92;dotsc, i_N' title='i_1, i_2, &#92;dotsc, i_N' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=I_1%2C+I_2%2C+%5Cdotsc%2C+I_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1, I_2, &#92;dotsc, I_N' title='I_1, I_2, &#92;dotsc, I_N' class='latex' /> with the formula at the end of <a href="http://pramook.wordpress.com/2009/07/11/more-tensor-lingo/">this blog post</a>. However, now that indices start at 0, we have that</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+c+%3D+%5Cbegin%7Bmatrix%7D+i_%7Bn%2B1%7D+I_%7Bn%2B2%7D+I_%7Bn%2B3%7D+I_%7Bn%2B4%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D+%2B+%5C%5C+i_%7Bn%2B2%7D+I_%7Bn%2B3%7D+I_%7Bn%2B4%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D+%2B+%5C%5C+i_%7Bn%2B3%7D+I_%7Bn%2B4%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D+%2B+%5C%5C+%5Cvdots+%5C%5C+i_%7Bn-3%7D+I_%7Bn-2%7D+I_%7Bn-1%7D%2B+%5C%5C+i_%7Bn-2%7D+I_%7Bn-1%7D+%2B+%5C%5C+i_%7Bn-1%7D+%5Cend%7Bmatrix%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle c = &#92;begin{matrix} i_{n+1} I_{n+2} I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; i_{n+2} I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; i_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; &#92;vdots &#92;&#92; i_{n-3} I_{n-2} I_{n-1}+ &#92;&#92; i_{n-2} I_{n-1} + &#92;&#92; i_{n-1} &#92;end{matrix}' title='&#92;displaystyle c = &#92;begin{matrix} i_{n+1} I_{n+2} I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; i_{n+2} I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; i_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; &#92;vdots &#92;&#92; i_{n-3} I_{n-2} I_{n-1}+ &#92;&#92; i_{n-2} I_{n-1} + &#92;&#92; i_{n-1} &#92;end{matrix}' class='latex' /></p>
<p>To simplify the notation, let <img src='http://s0.wp.com/latex.php?latex=s_k&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='s_k' title='s_k' class='latex' /> (<img src='http://s0.wp.com/latex.php?latex=s&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='s' title='s' class='latex' /> stands for &#8220;stride&#8221;) be equal to the number that gets multiplied to <img src='http://s0.wp.com/latex.php?latex=i_k&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_k' title='i_k' class='latex' /> so that we have </p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=c+%3D+i_%7Bn%2B1%7D+s_%7Bn%2B1%7D+%2B+i_%7Bn%2B2%7D+s_%7Bn%2B2%7D+%2B+%5Cdotsb+%2B+i_%7BN-1%7D+s_%7BN-1%7D+%2B+i_0+s_0+%2B+i_1+s_1+%2B+%5Cdotsb+%2B+i_%7Bn-1%7D+s_%7Bn-1%7D.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='c = i_{n+1} s_{n+1} + i_{n+2} s_{n+2} + &#92;dotsb + i_{N-1} s_{N-1} + i_0 s_0 + i_1 s_1 + &#92;dotsb + i_{n-1} s_{n-1}.' title='c = i_{n+1} s_{n+1} + i_{n+2} s_{n+2} + &#92;dotsb + i_{N-1} s_{N-1} + i_0 s_0 + i_1 s_1 + &#92;dotsb + i_{n-1} s_{n-1}.' class='latex' /></p>
<p>Let <img src='http://s0.wp.com/latex.php?latex=%5Cmathrm%7Bmo%7D%5B+%5Ccdot+%5D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathrm{mo}[ &#92;cdot ]' title='&#92;mathrm{mo}[ &#92;cdot ]' class='latex' /> (<img src='http://s0.wp.com/latex.php?latex=%5Cmathrm%7Bmo%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathrm{mo}' title='&#92;mathrm{mo}' class='latex' /> stands for &#8220;mode order&#8221;) be the list of modes ordered from the slowest varying to the fastest varying, which we got from <code>__get_unfolding_mode_order</code>. Recall that <img src='http://s0.wp.com/latex.php?latex=%5Cmathrm%7Bmo%7D%5B0%5D+%3D+n%2B1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathrm{mo}[0] = n+1' title='&#92;mathrm{mo}[0] = n+1' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=%5Cmathrm%7Bmo%7D%5B1%5D+%3D+n%2B2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathrm{mo}[1] = n+2' title='&#92;mathrm{mo}[1] = n+2' class='latex' />, &#8230;, <img src='http://s0.wp.com/latex.php?latex=%5Cmathrm%7Bmo%7D%5BN-2%5D+%3D+n-1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathrm{mo}[N-2] = n-1' title='&#92;mathrm{mo}[N-2] = n-1' class='latex' />. Then, we have that</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+s_%7B%5Cmathrm%7Bmo%7D%5Bk%5D%7D+%3D+%5Cbegin%7Bcases%7D+1%2C+%26+k+%3D+%7BN-2%7D%5C%5C+I_%7B%5Cmathrm%7Bmo%7D%5Bk%2B1%5D%7D+s_%7B%5Cmathrm%7Bmo%7D%5Bk%2B1%5D%7D%2C+%26+0+%5Cleq+k+%5Cleq+N-3+%5Cend%7Bcases%7D+&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle s_{&#92;mathrm{mo}[k]} = &#92;begin{cases} 1, &amp; k = {N-2}&#92;&#92; I_{&#92;mathrm{mo}[k+1]} s_{&#92;mathrm{mo}[k+1]}, &amp; 0 &#92;leq k &#92;leq N-3 &#92;end{cases} ' title='&#92;displaystyle s_{&#92;mathrm{mo}[k]} = &#92;begin{cases} 1, &amp; k = {N-2}&#92;&#92; I_{&#92;mathrm{mo}[k+1]} s_{&#92;mathrm{mo}[k+1]}, &amp; 0 &#92;leq k &#92;leq N-3 &#92;end{cases} ' class='latex' /></p>
<p>Then, we can write a function to compute the strides, given the mode order, as follow:</p>
<p><pre class="brush: python;">
def __get_unfolding_stride(A, mode_order):
    stride = [0 for i in xrange(A.ndim)]
    stride[mode_order[A.ndim-2]] = 1
    for i in xrange(A.ndim-3, -1, -1):
        stride[mode_order[i]] = (
            A.shape[mode_order[i+1]] * stride[mode_order[i+1]])
    return stride
</pre></p>
<p>And we have that</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+i_%7B%5Cmathrm%7Bmo%7D%5Bk%5D%7D+%3D+%5Cbegin%7Bcases%7D+c%5C+%5Cmathrm%7Bdiv%7D%5C+s_%7B%5Cmathrm%7Bmo%7D%5Bk%5D%7D%2C+%26+k+%3D+0%5C%5C+%28c%5C+%5Cmathrm%7Bmod%7D%5C+s_%7B%5Cmathrm%7Bmo%7D%5Bk-1%5D%7D%29%5C+%5Cmathrm%7Bdiv%7D%5C+s_%7B%5Cmathrm%7Bmo%7D%5Bk%5D%7D+%2C+%26+1+%5Cleq+k+%5Cleq+N-2+%5Cend%7Bcases%7D+&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle i_{&#92;mathrm{mo}[k]} = &#92;begin{cases} c&#92; &#92;mathrm{div}&#92; s_{&#92;mathrm{mo}[k]}, &amp; k = 0&#92;&#92; (c&#92; &#92;mathrm{mod}&#92; s_{&#92;mathrm{mo}[k-1]})&#92; &#92;mathrm{div}&#92; s_{&#92;mathrm{mo}[k]} , &amp; 1 &#92;leq k &#92;leq N-2 &#92;end{cases} ' title='&#92;displaystyle i_{&#92;mathrm{mo}[k]} = &#92;begin{cases} c&#92; &#92;mathrm{div}&#92; s_{&#92;mathrm{mo}[k]}, &amp; k = 0&#92;&#92; (c&#92; &#92;mathrm{mod}&#92; s_{&#92;mathrm{mo}[k-1]})&#92; &#92;mathrm{div}&#92; s_{&#92;mathrm{mo}[k]} , &amp; 1 &#92;leq k &#92;leq N-2 &#92;end{cases} ' class='latex' /></p>
<p>So, we can write a function to compute the indices as follows:</p>
<p><pre class="brush: python;">
def __get_tensor_indices(r, c, A, n, mode_order, stride):
    i = [0 for j in xrange(A.ndim)]
    i[n] = r
    i[mode_order[0]] = c / stride[mode_order[0]]
    for k in xrange(1, A.ndim-1):
        i[mode_order[k]] = (
            (c % stride[mode_order[k-1]]) / stride[mode_order[k]])
    return i
</pre></p>
<p>We need to create the result matrix. Thus, we need to now its size, which can be computed easily like below:</p>
<p><pre class="brush: python;">
def get_unfolding_matrix_size(A, n):
    row_count = A.shape[n]    
    col_count = 1    
    for i in xrange(A.ndim):
        if i != n: col_count *= A.shape[i]        
    return (row_count, col_count)
</pre></p>
<p>We are now ready to unfold:</p>
<p><pre class="brush: python;">
def unfold(A, n):
    &quot;&quot;&quot;
    Unfold tensor A along Mode n
    &quot;&quot;&quot;
    (row_count, col_count) = get_unfolding_matrix_size(A, n)
    result = numpy.zeros((row_count, col_count))
    
    mode_order = __get_unfolding_mode_order(A, n)
    stride = __get_unfolding_stride(A, mode_order)
        
    for r in xrange(row_count):        
        for c in xrange(col_count):
            i = __get_tensor_indices(r, c, A, n, mode_order, stride)            
            result[r, c] = A.__getitem__(i)

    return result
</pre><br />
Let&#8217;s test the code with the <img src='http://s0.wp.com/latex.php?latex=2+%5Ctimes+2+%5Ctimes+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2 &#92;times 2 &#92;times 2' title='2 &#92;times 2 &#92;times 2' class='latex' /> we used to illustrate tensor unfolding last time:<br />
<pre class="brush: python;">
&gt;&gt;&gt; A = numpy.zeros((2,2,2))
&gt;&gt;&gt; A[0,0,0] = 0
&gt;&gt;&gt; A[0,0,1] = 1
&gt;&gt;&gt; A[0,1,0] = 2
&gt;&gt;&gt; A[0,1,1] = 3
&gt;&gt;&gt; A[1,0,0] = 4
&gt;&gt;&gt; A[1,0,1] = 5
&gt;&gt;&gt; A[1,1,0] = 6
&gt;&gt;&gt; A[1,1,1] = 7
&gt;&gt;&gt; print unfold(A,0)
[[ 0.  1.  2.  3.]
 [ 4.  5.  6.  7.]]
&gt;&gt;&gt; print unfold(A,1)
[[ 0.  4.  1.  5.]
 [ 2.  6.  3.  7.]]
&gt;&gt;&gt; print unfold(A,2)
[[ 0.  2.  4.  6.]
 [ 1.  3.  5.  7.]]
</pre><br />
Seems like everything is working well. ^_^</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/103/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=103&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2009/07/14/tensor-unfolding-with-numpy/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploiting Inter-pixel Coherence</title>
		<link>http://pramook.wordpress.com/2009/07/13/exploiting-inter-pixel-coherence/</link>
		<comments>http://pramook.wordpress.com/2009/07/13/exploiting-inter-pixel-coherence/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 16:40:30 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[computer graphics]]></category>
		<category><![CDATA[compressive sensing]]></category>
		<category><![CDATA[precomputed radiance transfer]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=89</guid>
		<description><![CDATA[Recall the measurement equation from last time: Suppose again that the responses of the pixels to each light source are coherent. That is, we may hope that there is a basis such that the columns of are sparse. Then, we &#8230; <a href="http://pramook.wordpress.com/2009/07/13/exploiting-inter-pixel-coherence/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=89&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recall the measurement equation from last time:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cdisplaystyle+C%5ET+%3D+%28L%5ET+B%29+%5Chat%7BT%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;displaystyle C^T = (L^T B) &#92;hat{T}' title='&#92;displaystyle C^T = (L^T B) &#92;hat{T}' class='latex' /></p>
<p>Suppose again that the responses of the pixels to each light source are <em>coherent</em>. That is, we may hope that there is a basis <img src='http://s0.wp.com/latex.php?latex=V&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='V' title='V' class='latex' /> such that the columns of <img src='http://s0.wp.com/latex.php?latex=%5Ctilde%7BT%7D%5ET+%3D+V%5ET+%5Chat%7BT%7D%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;tilde{T}^T = V^T &#92;hat{T}^T' title='&#92;tilde{T}^T = V^T &#92;hat{T}^T' class='latex' /> are sparse. Then, we have that </p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=C%5ET+%3D+%28L%5ET+B%29+%5Ctilde%7BT%7D+V%5ET%2C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T = (L^T B) &#92;tilde{T} V^T,' title='C^T = (L^T B) &#92;tilde{T} V^T,' class='latex' /></p>
<p>or</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=C%5ET+V+%3D+%28L%5ET+B%29+%5Ctilde%7BT%7D.&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T V = (L^T B) &#92;tilde{T}.' title='C^T V = (L^T B) &#92;tilde{T}.' class='latex' /></p>
<p><span id="more-89"></span><br />
That is, as long as <img src='http://s0.wp.com/latex.php?latex=%5Ctilde%7BT%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;tilde{T}' title='&#92;tilde{T}' class='latex' />&#8216;s columns are sparse, we can infer it&#8217;s columns by working instead with the new measurements <img src='http://s0.wp.com/latex.php?latex=C%5ET+V&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T V' title='C^T V' class='latex' />, which is basically <img src='http://s0.wp.com/latex.php?latex=C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C' title='C' class='latex' /> projected into <img src='http://s0.wp.com/latex.php?latex=V&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='V' title='V' class='latex' />. One certainly hope that the columns of <img src='http://s0.wp.com/latex.php?latex=%5Ctilde%7BT%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;tilde{T}' title='&#92;tilde{T}' class='latex' /> are even sparser than the columns of <img src='http://s0.wp.com/latex.php?latex=%5Chat%7BT%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{T}' title='&#92;hat{T}' class='latex' />. If so, the number of measurements can be reduced greatly. However, I&#8217;m not so sure about this myself when it comes to wavelets, which is the basis I&#8217;m most likely to use.</p>
<p>Again, one can see that a big bottleneck in the above equation: to compute <img src='http://s0.wp.com/latex.php?latex=C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C' title='C' class='latex' />, we have to measure the color of <em>every pixel</em> of under <em>every lighting condition</em> used for measurement. And we know that measure the color of a pixel accurately takes a large number of rays. Actually, <img src='http://s0.wp.com/latex.php?latex=C%5ET+V&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T V' title='C^T V' class='latex' /> might be sparse in its rows. Can we acquire them with compressive sensing as well?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=89&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2009/07/13/exploiting-inter-pixel-coherence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>Compressive Sensing and Precomputed Radiance Transfer?</title>
		<link>http://pramook.wordpress.com/2009/07/12/compressive-sensing-and-prt/</link>
		<comments>http://pramook.wordpress.com/2009/07/12/compressive-sensing-and-prt/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 17:52:10 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[computer graphics]]></category>
		<category><![CDATA[compressive sensing]]></category>
		<category><![CDATA[precomputed light transport]]></category>
		<category><![CDATA[research idea]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=67</guid>
		<description><![CDATA[Following the development in Peers et. al.&#8217;s Compressive Light Transport Sensing (download), the light transport problem can be described by the following matrix equation: where is a -dimensional vector, where is the number of pixels in the final image, and &#8230; <a href="http://pramook.wordpress.com/2009/07/12/compressive-sensing-and-prt/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=67&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Following the development in Peers et. al.&#8217;s <em>Compressive Light Transport Sensing</em> (<a href="http://www1.cs.columbia.edu/~dhruv/transportacquisition/clts.pdf">download</a>), the light transport problem can be described by the following matrix equation:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bc%7D+%3D+T%5ET+%5Cmathbf%7Bl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{c} = T^T &#92;mathbf{l}' title='&#92;mathbf{c} = T^T &#92;mathbf{l}' class='latex' /></p>
<p><span id="more-67"></span><br />
where</p>
<ul>
<li><img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bc%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{c}' title='&#92;mathbf{c}' class='latex' /> is a <img src='http://s0.wp.com/latex.php?latex=p&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='p' title='p' class='latex' />-dimensional vector, where <img src='http://s0.wp.com/latex.php?latex=p&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='p' title='p' class='latex' /> is the number of pixels in the final image, and each component of <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bc%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{c}' title='&#92;mathbf{c}' class='latex' /> is the color of a pixel,</li>
<li><img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{l}' title='&#92;mathbf{l}' class='latex' /> is an <img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' />-dimensional vector, where <img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' /> is the number of light sources, and each component of <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{l}' title='&#92;mathbf{l}' class='latex' /> is the intensity of a light source, and</li>
<li><img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7BT%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{T}' title='&#92;mathbf{T}' class='latex' /> is a transfer matrix of size <img src='http://s0.wp.com/latex.php?latex=n+%5Ctimes+p&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n &#92;times p' title='n &#92;times p' class='latex' />.</li>
</ul>
<p>The <img src='http://s0.wp.com/latex.php?latex=i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i' title='i' class='latex' />-th column of <img src='http://s0.wp.com/latex.php?latex=T&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='T' title='T' class='latex' />, which we shall denode by <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bt%7D_i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{t}_i' title='&#92;mathbf{t}_i' class='latex' />, allows us to write the color <img src='http://s0.wp.com/latex.php?latex=c_i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='c_i' title='c_i' class='latex' /> of Pixel <img src='http://s0.wp.com/latex.php?latex=i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i' title='i' class='latex' /> as <img src='http://s0.wp.com/latex.php?latex=c_i+%3D+%5Cmathbf%7Bt%7D_i%5ET+%5Cmathbf%7Bl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='c_i = &#92;mathbf{t}_i^T &#92;mathbf{l}' title='c_i = &#92;mathbf{t}_i^T &#92;mathbf{l}' class='latex' />.</p>
<p>Each <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bt%7D_i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{t}_i' title='&#92;mathbf{t}_i' class='latex' /> is a signal the paper wishes to learn from real measurements. A measurement consists of shining a predetermined pattern of light to the scene and take a photograph. So let&#8217;s say we make <img src='http://s0.wp.com/latex.php?latex=m&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='m' title='m' class='latex' /> measurements. Now, the light vector <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bl%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{l}' title='&#92;mathbf{l}' class='latex' /> becomes a matrix <img src='http://s0.wp.com/latex.php?latex=L&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='L' title='L' class='latex' /> of size <img src='http://s0.wp.com/latex.php?latex=n+%5Ctimes+m&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n &#92;times m' title='n &#92;times m' class='latex' />, the color vector <img src='http://s0.wp.com/latex.php?latex=C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C' title='C' class='latex' /> of size <img src='http://s0.wp.com/latex.php?latex=p+%5Ctimes+m&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='p &#92;times m' title='p &#92;times m' class='latex' />, and the equation changes to:</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=C+%3D+T%5ET+L&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C = T^T L' title='C = T^T L' class='latex' /></p>
<p>or, if you prefer to write the signal we want to reconstruct at the end,</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=C%5ET+%3D+L%5ET+T&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T = L^T T' title='C^T = L^T T' class='latex' />.</p>
<p>Notice that the above equation gives rise to <img src='http://s0.wp.com/latex.php?latex=p&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='p' title='p' class='latex' /> indepedent signal reconstruction problems for each column where <img src='http://s0.wp.com/latex.php?latex=L%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='L^T' title='L^T' class='latex' /> acts like a measurement ensemble.</p>
<p>Suppose that each <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7BT%7D_i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{T}_i' title='&#92;mathbf{T}_i' class='latex' /> is sparse in some basis <img src='http://s0.wp.com/latex.php?latex=B&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='B' title='B' class='latex' />, having at most <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7BS%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{S}' title='&#92;mathbf{S}' class='latex' /> non-zero terms. We have that</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=C%5ET+%3D+L%5ET+T+%3D+L%5ET+B+B%5ET+T+%3D+%28L%5ET+B%29+%5Chat%7BT%7D+&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='C^T = L^T T = L^T B B^T T = (L^T B) &#92;hat{T} ' title='C^T = L^T T = L^T B B^T T = (L^T B) &#92;hat{T} ' class='latex' />.</p>
<p>where <img src='http://s0.wp.com/latex.php?latex=%5Chat%7BT%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;hat{T}' title='&#92;hat{T}' class='latex' /> is <img src='http://s0.wp.com/latex.php?latex=T&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='T' title='T' class='latex' /> projected into <img src='http://s0.wp.com/latex.php?latex=B&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='B' title='B' class='latex' />.</p>
<p>The theory of compressive sensing states that, if <img src='http://s0.wp.com/latex.php?latex=L%5ET+B&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='L^T B' title='L^T B' class='latex' /> satisfies the <i>restricted isometry property</i> (read more about this property <a href="http://dsp.rice.edu/files/cs/CSintro.pdf">here</a>) and</p>
<p style="text-align:center;"><img src='http://s0.wp.com/latex.php?latex=m+%5Cgeq+%5Calpha+S+%5Clog+n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='m &#92;geq &#92;alpha S &#92;log n' title='m &#92;geq &#92;alpha S &#92;log n' class='latex' />.</p>
<p>some constant <img src='http://s0.wp.com/latex.php?latex=%5Calpha&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;alpha' title='&#92;alpha' class='latex' />, then we construct each <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bt%7D_i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{t}_i' title='&#92;mathbf{t}_i' class='latex' /> exactly or with minimal error.</p>
<h3>Application to Precomputed Radiance Transfer?</h3>
<p>Can we apply the above compressive sensing framework to PRT? After all, the core tasks of image relighting and PRT are the same: learning the transfer function of each pixel. The difference is that measurements in PRT are done in computer by tracing rays.</p>
<p>It&#8217;s possible. In the scenario that you would like to relight a scene by a high resolution environmental map, say <img src='http://s0.wp.com/latex.php?latex=256+%5Ctimes+256+%5Ctimes+6&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='256 &#92;times 256 &#92;times 6' title='256 &#92;times 256 &#92;times 6' class='latex' /> (as done in <a href="http://graphics.stanford.edu/papers/allfreqmat/glossy_allfreq.300dpi.pdf">this paper</a>). The transfer vector <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Bt%7D_i&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{t}_i' title='&#92;mathbf{t}_i' class='latex' /> for each pixel would also be that high in dimension. To enable real time relighting, we wavelet-transform these transfer functions and keep only about 200 largest coefficients. Here, <img src='http://s0.wp.com/latex.php?latex=%5Clog_2+n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;log_2 n' title='&#92;log_2 n' class='latex' /> is about 20. So, we can render about 4000 images and use it to reconstruct the functions.</p>
<p>However, all of the above is not so impressive. First, it might take a very long time to render that 4000 images accurately. Second, we only assume that each pixel has one color, which either mean that the view is fixed or all the material is diffuse. Again, I don&#8217;t know how to handle variable views yet, but surveying more literature might help.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=67&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2009/07/12/compressive-sensing-and-prt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>More Tensor Lingo</title>
		<link>http://pramook.wordpress.com/2009/07/11/more-tensor-lingo/</link>
		<comments>http://pramook.wordpress.com/2009/07/11/more-tensor-lingo/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 16:28:37 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[math]]></category>
		<category><![CDATA[linear algebra]]></category>
		<category><![CDATA[multilinear algebra]]></category>
		<category><![CDATA[tensor]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=27</guid>
		<description><![CDATA[Continuing from last time, we will be talking more about tensor notations. n-mode Vectors Let be an tensor. An -mode vector of is an -vector obtained from by fixing indices but let vary. Example 1: Let be a tensor with &#8230; <a href="http://pramook.wordpress.com/2009/07/11/more-tensor-lingo/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=27&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Continuing from last time, we will be talking more about tensor notations.<span id="more-27"></span></p>
<h3>n-mode Vectors</h3>
<p>Let <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> be an <img src='http://s0.wp.com/latex.php?latex=I_1+%5Ctimes+I_2+%5Ctimes+%5Cdotsb+%5Ctimes+I_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' title='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' class='latex' /> tensor. An <i><img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' />-mode vector</i> of <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> is an <img src='http://s0.wp.com/latex.php?latex=I_n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_n' title='I_n' class='latex' />-vector obtained from <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> by fixing indices <img src='http://s0.wp.com/latex.php?latex=i_1%2C+i_2%2C+%5Cdotsc%2C+i_%7Bn-1%7D%2C+i_%7Bn%2B1%7D%2C+%5Cdotsc%2C+i_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1, i_2, &#92;dotsc, i_{n-1}, i_{n+1}, &#92;dotsc, i_N' title='i_1, i_2, &#92;dotsc, i_{n-1}, i_{n+1}, &#92;dotsc, i_N' class='latex' /> but let <img src='http://s0.wp.com/latex.php?latex=i_n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_n' title='i_n' class='latex' /> vary.</p>
<blockquote><p>
<b>Example 1:</b> Let <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> be a <img src='http://s0.wp.com/latex.php?latex=2%5Ctimes+2+%5Ctimes+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2&#92;times 2 &#92;times 2' title='2&#92;times 2 &#92;times 2' class='latex' /> tensor with <img src='http://s0.wp.com/latex.php?latex=a_%7B111%7D+%3D+0&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{111} = 0' title='a_{111} = 0' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=a_%7B112%7D+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{112} = 1' title='a_{112} = 1' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=a_%7B121%7D+%3D+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{121} = 2' title='a_{121} = 2' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=a_%7B122%7D+%3D+3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{122} = 3' title='a_{122} = 3' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=a_%7B211%7D+%3D+4&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{211} = 4' title='a_{211} = 4' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=a_%7B212%7D+%3D+5&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{212} = 5' title='a_{212} = 5' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=a_%7B221%7D+%3D+6&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{221} = 6' title='a_{221} = 6' class='latex' />,  and <img src='http://s0.wp.com/latex.php?latex=a_%7B222%7D+%3D+7&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{222} = 7' title='a_{222} = 7' class='latex' />. </p>
<p>Fixing <img src='http://s0.wp.com/latex.php?latex=i_1+%3D+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1 = 2' title='i_1 = 2' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=i_2+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2 = 1' title='i_2 = 1' class='latex' />, and letting <img src='http://s0.wp.com/latex.php?latex=i_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3' title='i_3' class='latex' /> vary, we get the 3-mode vector <img src='http://s0.wp.com/latex.php?latex=%284%2C5%29%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(4,5)^T' title='(4,5)^T' class='latex' />. </p>
<p>Fixing <img src='http://s0.wp.com/latex.php?latex=i_2+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2 = 1' title='i_2 = 1' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=i_3+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3 = 1' title='i_3 = 1' class='latex' />, and letting <img src='http://s0.wp.com/latex.php?latex=i_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1' title='i_1' class='latex' /> vary, we get the 1-mode vector <img src='http://s0.wp.com/latex.php?latex=%280%2C4%29%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(0,4)^T' title='(0,4)^T' class='latex' />. </p>
<p>Fixing <img src='http://s0.wp.com/latex.php?latex=i_3+%3D+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3 = 2' title='i_3 = 2' class='latex' />, <img src='http://s0.wp.com/latex.php?latex=i_1+%3D+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1 = 2' title='i_1 = 2' class='latex' />, and letting <img src='http://s0.wp.com/latex.php?latex=i_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2' title='i_2' class='latex' /> vary, we get the 2-mode vector <img src='http://s0.wp.com/latex.php?latex=%285%2C7%29%5ET&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(5,7)^T' title='(5,7)^T' class='latex' />.
</p></blockquote>
<h3>Matrix Unfolding</h3>
<p>Matrix unfolding is a way to represent a tensor as a matrix. The concept is easy to grasp, but tedious to describe mathematically. So let us start with some examples on 3-mode tensors.</p>
<p>Let <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> be an <img src='http://s0.wp.com/latex.php?latex=I_1+%5Ctimes+I_2+%5Ctimes+I_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1 &#92;times I_2 &#92;times I_3' title='I_1 &#92;times I_2 &#92;times I_3' class='latex' /> tensor. It has three different matrix unfoldings <img src='http://s0.wp.com/latex.php?latex=A_%7B%281%29%7D%2C+A_%7B%282%29%7D%2C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(1)}, A_{(2)},' title='A_{(1)}, A_{(2)},' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=A_%7B%283%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(3)}' title='A_{(3)}' class='latex' />, corresponding to its three modes. <img src='http://s0.wp.com/latex.php?latex=A_%7B%281%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(1)}' title='A_{(1)}' class='latex' /> has <img src='http://s0.wp.com/latex.php?latex=I_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1' title='I_1' class='latex' /> rows and <img src='http://s0.wp.com/latex.php?latex=I_2I_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_2I_3' title='I_2I_3' class='latex' /> columns where the columns are the 1-mode vectors of <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' />. The columns are ordered so that the index <img src='http://s0.wp.com/latex.php?latex=i_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3' title='i_3' class='latex' /> varies faster than <img src='http://s0.wp.com/latex.php?latex=i_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2' title='i_2' class='latex' />. So, the first column corresponds to the 1-mode vector where <img src='http://s0.wp.com/latex.php?latex=i_2+%3D+i_3+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2 = i_3 = 1' title='i_2 = i_3 = 1' class='latex' />. The second column corresponds to <img src='http://s0.wp.com/latex.php?latex=i_2+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2 = 1' title='i_2 = 1' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=i_3+%3D+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3 = 2' title='i_3 = 2' class='latex' />. The <img src='http://s0.wp.com/latex.php?latex=%28I_3%2B1%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='(I_3+1)' title='(I_3+1)' class='latex' />-st column corresponds to <img src='http://s0.wp.com/latex.php?latex=i_2+%3D+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2 = 2' title='i_2 = 2' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=i_3+%3D+1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3 = 1' title='i_3 = 1' class='latex' />. In general, the 1-mode vector with <img src='http://s0.wp.com/latex.php?latex=i_2+%3D+a&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2 = a' title='i_2 = a' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=i_3+%3D+b&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3 = b' title='i_3 = b' class='latex' /> appears as the <img src='http://s0.wp.com/latex.php?latex=%28%28a-1%29I_2+%2B+b%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='((a-1)I_2 + b)' title='((a-1)I_2 + b)' class='latex' />-th column.</p>
<p>Analogously, <img src='http://s0.wp.com/latex.php?latex=A_%7B%282%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(2)}' title='A_{(2)}' class='latex' /> has <img src='http://s0.wp.com/latex.php?latex=I_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_2' title='I_2' class='latex' /> rows and <img src='http://s0.wp.com/latex.php?latex=I_3+I_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_3 I_1' title='I_3 I_1' class='latex' /> columns. Here, the 2-mode vector with <img src='http://s0.wp.com/latex.php?latex=i_3+%3D+a&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3 = a' title='i_3 = a' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=i_1+%3D+b&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1 = b' title='i_1 = b' class='latex' /> appears as the <img src='http://s0.wp.com/latex.php?latex=%28%28a-1%29I_3+%2B+b%29&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='((a-1)I_3 + b)' title='((a-1)I_3 + b)' class='latex' />-th column. Notice that <img src='http://s0.wp.com/latex.php?latex=i_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1' title='i_1' class='latex' /> varies faster than <img src='http://s0.wp.com/latex.php?latex=i_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3' title='i_3' class='latex' />. In general, when we say that <img src='http://s0.wp.com/latex.php?latex=A_%7B%282%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(2)}' title='A_{(2)}' class='latex' /> (or any other unfolded matrices) is of size <img src='http://s0.wp.com/latex.php?latex=I_2+%5Ctimes+I_3+I_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_2 &#92;times I_3 I_1' title='I_2 &#92;times I_3 I_1' class='latex' />, we mean that <img src='http://s0.wp.com/latex.php?latex=i_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1' title='i_1' class='latex' /> (the number to the right) varies faster than <img src='http://s0.wp.com/latex.php?latex=i_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_3' title='i_3' class='latex' /> (the number of the left).</p>
<p>A similar situation goes for <img src='http://s0.wp.com/latex.php?latex=A_%7B%283%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(3)}' title='A_{(3)}' class='latex' />. It has <img src='http://s0.wp.com/latex.php?latex=I_3&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_3' title='I_3' class='latex' /> row and <img src='http://s0.wp.com/latex.php?latex=I_1+I_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1 I_2' title='I_1 I_2' class='latex' /> columns with index <img src='http://s0.wp.com/latex.php?latex=i_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1' title='i_1' class='latex' /> varies more slowly than <img src='http://s0.wp.com/latex.php?latex=i_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2' title='i_2' class='latex' />.</p>
<blockquote><p>
<b>Example 2:</b> Let <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> be the tensor in Example 1. The three matrix unfoldings of <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> are given below:</p>
<p><img src='http://s0.wp.com/latex.php?latex=A_%7B%281%29%7D+%3D+%5Cbegin%7Bbmatrix%7D+0+%26+1+%26+2+%26+3%5C%5C+4+%26+5+%26+6+%26+7%5Cend%7Bbmatrix%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(1)} = &#92;begin{bmatrix} 0 &amp; 1 &amp; 2 &amp; 3&#92;&#92; 4 &amp; 5 &amp; 6 &amp; 7&#92;end{bmatrix}' title='A_{(1)} = &#92;begin{bmatrix} 0 &amp; 1 &amp; 2 &amp; 3&#92;&#92; 4 &amp; 5 &amp; 6 &amp; 7&#92;end{bmatrix}' class='latex' /></p>
<p><img src='http://s0.wp.com/latex.php?latex=A_%7B%282%29%7D+%3D+%5Cbegin%7Bbmatrix%7D+0+%26+4+%26+1+%26+5%5C%5C+2+%26+6+%26+3+%26+7%5Cend%7Bbmatrix%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(2)} = &#92;begin{bmatrix} 0 &amp; 4 &amp; 1 &amp; 5&#92;&#92; 2 &amp; 6 &amp; 3 &amp; 7&#92;end{bmatrix}' title='A_{(2)} = &#92;begin{bmatrix} 0 &amp; 4 &amp; 1 &amp; 5&#92;&#92; 2 &amp; 6 &amp; 3 &amp; 7&#92;end{bmatrix}' class='latex' /></p>
<p><img src='http://s0.wp.com/latex.php?latex=A_%7B%283%29%7D+%3D+%5Cbegin%7Bbmatrix%7D+0+%26+2+%26+4+%26+6%5C%5C+1+%26+3+%26+5+%26+7%5Cend%7Bbmatrix%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(3)} = &#92;begin{bmatrix} 0 &amp; 2 &amp; 4 &amp; 6&#92;&#92; 1 &amp; 3 &amp; 5 &amp; 7&#92;end{bmatrix}' title='A_{(3)} = &#92;begin{bmatrix} 0 &amp; 2 &amp; 4 &amp; 6&#92;&#92; 1 &amp; 3 &amp; 5 &amp; 7&#92;end{bmatrix}' class='latex' />
</p></blockquote>
<p>In general, a matrix unfolding of an <img src='http://s0.wp.com/latex.php?latex=I_1+%5Ctimes+I_2+%5Ctimes+%5Cdotsb+%5Ctimes+I_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' title='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' class='latex' /> tensor <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> along the <img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' />-mode is an <img src='http://s0.wp.com/latex.php?latex=I_n+%5Ctimes+I_%7Bn%2B1%7D+I_%7Bn%2B2%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_n &#92;times I_{n+1} I_{n+2} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1}' title='I_n &#92;times I_{n+1} I_{n+2} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1}' class='latex' /> matrix <img src='http://s0.wp.com/latex.php?latex=A_%7B%28n%29%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A_{(n)}' title='A_{(n)}' class='latex' /> whose columns are the <img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' />-mode vectors, and the columns are arranged such that the index <img src='http://s0.wp.com/latex.php?latex=i_%7Bn-1%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_{n-1}' title='i_{n-1}' class='latex' /> varies the fastest and <img src='http://s0.wp.com/latex.php?latex=i_%7Bn%2B1%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_{n+1}' title='i_{n+1}' class='latex' /> the slowest. To be pedantic, we can specify exactly where the element <img src='http://s0.wp.com/latex.php?latex=a_%7Bi_1+i_2+%5Cdotsm+i_N%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{i_1 i_2 &#92;dotsm i_N}' title='a_{i_1 i_2 &#92;dotsm i_N}' class='latex' /> appears in <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' />. It appears on Row <img src='http://s0.wp.com/latex.php?latex=i_n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_n' title='i_n' class='latex' /> and on Column </p>
<p><img src='http://s0.wp.com/latex.php?latex=%5Cbegin%7Bmatrix%7D+%28i_%7Bn%2B1%7D-1%29+I_%7Bn%2B2%7D+I_%7Bn%2B3%7D+I_%7Bn%2B4%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D+%2B+%5C%5C+%28i_%7Bn%2B2%7D-1%29+I_%7Bn%2B3%7D+I_%7Bn%2B4%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D+%2B+%5C%5C+%28i_%7Bn%2B3%7D-1%29+I_%7Bn%2B4%7D+%5Cdotsm+I_N+I_1+I_2+%5Cdotsm+I_%7Bn-1%7D+%2B+%5C%5C+%5Cvdots+%5C%5C+%28i_%7Bn-3%7D-1%29+I_%7Bn-2%7D+I_%7Bn-1%7D%2B+%5C%5C+%28i_%7Bn-2%7D-1%29+I_%7Bn-1%7D+%2B+%5C%5C+i_%7Bn-1%7D+%5Cend%7Bmatrix%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;begin{matrix} (i_{n+1}-1) I_{n+2} I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; (i_{n+2}-1) I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; (i_{n+3}-1) I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; &#92;vdots &#92;&#92; (i_{n-3}-1) I_{n-2} I_{n-1}+ &#92;&#92; (i_{n-2}-1) I_{n-1} + &#92;&#92; i_{n-1} &#92;end{matrix}' title='&#92;begin{matrix} (i_{n+1}-1) I_{n+2} I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; (i_{n+2}-1) I_{n+3} I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; (i_{n+3}-1) I_{n+4} &#92;dotsm I_N I_1 I_2 &#92;dotsm I_{n-1} + &#92;&#92; &#92;vdots &#92;&#92; (i_{n-3}-1) I_{n-2} I_{n-1}+ &#92;&#92; (i_{n-2}-1) I_{n-1} + &#92;&#92; i_{n-1} &#92;end{matrix}' class='latex' /></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=27&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2009/07/11/more-tensor-lingo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
		<item>
		<title>เทนเซอร์</title>
		<link>http://pramook.wordpress.com/2009/07/10/tensor/</link>
		<comments>http://pramook.wordpress.com/2009/07/10/tensor/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 18:26:34 +0000</pubDate>
		<dc:creator>cardcaptor</dc:creator>
				<category><![CDATA[math]]></category>
		<category><![CDATA[linear algebra]]></category>
		<category><![CDATA[multilinear algebra]]></category>
		<category><![CDATA[tensor]]></category>

		<guid isPermaLink="false">http://pramook.wordpress.com/?p=3</guid>
		<description><![CDATA[เราทราบกันดีว่า<strong>สเกลาร์</strong>คือตัวเลขหนึ่งตัว หากเรามีตัวเลขหลายตัวเรียงกันเป็นแถว เราสามารถแทนมันด้วย<strong>เวกเตอร์</strong> และถ้าเรามีเลขหลายตัวที่สามารถเรียงกันเป็นตารางสี่เหลี่ยมได้ เราสามารถแทนชุดตัวเลขนี้ด้วย<em>เมตริกซ์</em> ในกรณีที่เรามีตัวเลขหลายตัวที่สามารถเรียงกันได้เป็นปริซึมในสามมิติ หรือเป็นปริซึมในปริภูมิที่มีมิติมากกว่าสาม เราจะแทนตัวเลขเหล่านั้นด้วยวัตถุทางคณิตศาสตร์ที่เรียกว่า<strong>เทนเซอร์</strong> <a href="http://pramook.wordpress.com/2009/07/10/tensor/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=3&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>เราทราบกันดีว่า<strong>สเกลาร์</strong>คือตัวเลขหนึ่งตัว หากเรามีตัวเลขหลายตัวเรียงกันเป็นแถว เราสามารถแทนมันด้วย<strong>เวกเตอร์</strong> และถ้าเรามีเลขหลายตัวที่สามารถเรียงกันเป็นตารางสี่เหลี่ยมได้ เราสามารถแทนชุดตัวเลขนี้ด้วย<strong>เมตริกซ์</strong></p>
<p>ในกรณีที่เรามีตัวเลขหลายตัวที่สามารถเรียงกันได้เป็นปริซึมในสามมิติ หรือเป็นปริซึมในปริภูมิที่มีมิติมากกว่าสาม เราจะแทนตัวเลขเหล่านั้นด้วยวัตถุทางคณิตศาสตร์ที่เรียกว่า<strong>เทนเซอร์</strong><span id="more-3"></span></p>
<p>เราพบเห็นเทนเซอร์อยู่มากมายในชีวิตประจำวัน ตัวอย่างที่ดีที่สุดคือ <strong>วิดีโอ</strong> เนื่องจากวิดีโอถูกแบ่งออกเป็นหลายเฟรม แต่ละเฟรมคือรูปสองมิติหนึ่งรูป ซึ่งรูปสองมิตินี้จริงๆ แล้วเป็นตารางสี่เหลี่ยมจัตุรัสที่มีสีอยู่หนึ่งสี (จริงๆ แล้วสีหนึ่งสีต้องแทนด้วยเลขสามตัว แต่เพื่อความง่ายเราจะคิดว่าวิดีโอเป็นวิดีโอขาวดำ ซึ่งสีแต่ละสีแทนด้วยเลขเพียงตัวเดียวได้) ฉะนั้นเราจึงสามารถมองวิดีโอเป็นเทนเซอร์หรือปริซึมในปริภูมิสามมิติ ที่แกนหนึ่งคือความกว้างของภาพ อีกแกนหนึ่งคือความสูงของภาพ และอีกเกินหนึ่งคือเวลาได้</p>
<p>การมองวิดีโอและข้อมูลอื่นๆ เป็นเทนเซอร์นั้น ช่วยให้เรานำเทคนิตทางพีชคณิตเชิงเส้นมาวิเคราะห์้ข้อมูลพวกนี้ได้ และการวิเคราะห์เหล่านี้สามารถทำให้เราสามารถบีบอัดข้อมูลให้มีขนาดเล็กลงได้มาก แต่ก่อนที่เราจะสามารถพูดถึงเทคนิคเหล่านั้น เราจำเป็นจะต้องสร้างระบบสัญลักษณ์สำหรับเทนเซอร์เสียก่อน นี่เป็นเป้าหมายของบทความนี้</p>
<p>ระบบสัญลักษณ์ที่เราจะสร้างในที่นี้ส่วนใหญ่แล้วลอกมาจากเปเปอร์ <em>A Multilinear Singular Value Decomposition</em> ของ de Lathauwer, de Moor, และ Vandewalle (<a href="http://perso-etis.ensea.fr/~lathauwer/ldl-94-31.pdf">ดาวน์โหลด</a>) แต่จะมีการปรับปรุงให้อ่านง่ายขึ้นตามรสนิยมของผู้เขียน</p>
<p>ธรรมเนียมปฏิบัติในการเขียนสัญลักษณ์ของเราเป็นตัวต่อไปนี้</p>
<ul>
<li>
เราจะแทนปริมาณสเกลาร์ด้วยตัวพิมพ์เล็ก เช๋น <img src='http://s0.wp.com/latex.php?latex=x%2C++y%2C+a_1%2C+a_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='x,  y, a_1, a_2' title='x,  y, a_1, a_2' class='latex' /> เป็นต้น
</li>
<li>
เราจะแทนปริมาณเวกเตอร์ด้วยตัวพิมพ์เล็กหนา เช่น <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Ba%7D%2C+%5Cmathbf%7Bb%7D%2C+%5Cmathbf%7Bx%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{a}, &#92;mathbf{b}, &#92;mathbf{x}' title='&#92;mathbf{a}, &#92;mathbf{b}, &#92;mathbf{x}' class='latex' /> เป็นต้น
</li>
<li>
สเกลาร์ที่เป็นส่วนประกอบ (component) ของเวกเตอร์จะใช้ตัวอักษรเดียวกันกับเวกเตอร์นั้น เช่น <img src='http://s0.wp.com/latex.php?latex=x_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='x_2' title='x_2' class='latex' /> เป็นส่วนประกอบส่วนที่สองของเวกเตอร์ <img src='http://s0.wp.com/latex.php?latex=%5Cmathrm%7Bx%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathrm{x}' title='&#92;mathrm{x}' class='latex' /> เป็นต้น
</li>
<li>
เราแทนเมตริกซ์ด้วยตัวอักษรตัวพิืมพ์ใหญ่ เช่น <img src='http://s0.wp.com/latex.php?latex=A%2C+B%2C+X&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A, B, X' title='A, B, X' class='latex' /> เป็นต้น และเช่นเดียวกับเวกเตอร์ สเกลาร์ที่เป็นสมาชิกของเมตริกซ์จะใช้ตัวอักษรตัวภาษาอังกฤษเดียวกัน เช่น <img src='http://s0.wp.com/latex.php?latex=a_%7B12%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{12}' title='a_{12}' class='latex' /> คือสมาชิก ณ แถวที่ 1 คอลัมน์ที่ 2 ของเมตริกซ์ <img src='http://s0.wp.com/latex.php?latex=A&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A' title='A' class='latex' /> เป็นต้น นอกจากนี้ เวกเตอร์ที่ใช้ตัวอักษรเดียวกับเมตริกซ์จะแทน<em>คอลัมน์</em> (ไม่ใช่แถว) ของเมตริกซ์นั้น เช่น <img src='http://s0.wp.com/latex.php?latex=%5Cmathbf%7Ba%7D_5&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbf{a}_5' title='&#92;mathbf{a}_5' class='latex' /> คือคอลัมน์ที่ 5 ของเมตริกซ์ <img src='http://s0.wp.com/latex.php?latex=A&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='A' title='A' class='latex' /> เป็นต้น
</li>
</ul>
<h3>เทนเซอร์</h3>
<p><strong>เทนเซอร์</strong> คือ กลุ่มของตัวเลขที่สามารถนำมาเรียงกันเป็นปริซึมในปริภูมิหลายมิติได้ หากปริซึมนั้นมี <img src='http://s0.wp.com/latex.php?latex=N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='N' title='N' class='latex' /> มิติ เราจะเรียกว่าเทนเซอร์นั้นมี&#8221;&#8217;โหมด (mode)&#8221;&#8217; อยู่ <img src='http://s0.wp.com/latex.php?latex=N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='N' title='N' class='latex' /> โหมด</p>
<p>เราจะแทนเทนเซอร์ด้วยตัวอักษรภาษาอังกฤษที่ใช้ฟอนต์แบบ calligraphy (\mathcal ใน latex) เช่น <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D%2C+%5Cmathcal%7BB%7D%2C+%5Cmathcal%7BC%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}, &#92;mathcal{B}, &#92;mathcal{C}' title='&#92;mathcal{A}, &#92;mathcal{B}, &#92;mathcal{C}' class='latex' /> เป็นต้น </p>
<p>สมมติให้ <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> เป็นเทนเซอร์ที่มีโหมดอยู่ <img src='http://s0.wp.com/latex.php?latex=N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='N' title='N' class='latex' /> โหมด แล้วสมาชิกแต่ละตัวของ <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> จะต้องถูกอ้างอิงถึงด้วยตัวเลข <img src='http://s0.wp.com/latex.php?latex=N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='N' title='N' class='latex' /> ตัว เช่นเีดียวกับธรรมเนียมการเขียนสมาชิกของเวกเตอร์และเมตริกซ์ข้างต้น เราจะใช้ตัวอักษรภาษาอังกฤษตัวเดียวกับชื่อเทนเซอร์ในการระบุถึงสมาชิกของเทนเซอร์ตัวนั้น กล่าวคือ <img src='http://s0.wp.com/latex.php?latex=a_%7Bi_1+i_2+i_3+%5Cdotsm+i_N%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{i_1 i_2 i_3 &#92;dotsm i_N}' title='a_{i_1 i_2 i_3 &#92;dotsm i_N}' class='latex' /> คือสมาชิกของเทนเซอร์ <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> ณ ตำแหน่งที่ <img src='http://s0.wp.com/latex.php?latex=i_1&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1' title='i_1' class='latex' /> ในโหมดที่ 1, <img src='http://s0.wp.com/latex.php?latex=i_2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_2' title='i_2' class='latex' /> ในใหมดที่ 2 &#8230; และ <img src='http://s0.wp.com/latex.php?latex=i_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_N' title='i_N' class='latex' /> ในโหมดที่ <img src='http://s0.wp.com/latex.php?latex=n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='n' title='n' class='latex' /></p>
<p>หากเราใช้ตัวแปร <img src='http://s0.wp.com/latex.php?latex=i_1%2C+i_2%2C+%5Cdotsc%2C+i_n&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='i_1, i_2, &#92;dotsc, i_n' title='i_1, i_2, &#92;dotsc, i_n' class='latex' /> ในการบ่งตำแหน่งของสมาชิกของเทนเซอร์ <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> เราจะใช้ตัวแปร <img src='http://s0.wp.com/latex.php?latex=I_1%2C+I_2%2C+%5Cdotsc%2C+I_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1, I_2, &#92;dotsc, I_N' title='I_1, I_2, &#92;dotsc, I_N' class='latex' /> ในการบ่งถึงจำนวนสมาชิกในโหมดแต่ละโหมด กล่าวคือ <img src='http://s0.wp.com/latex.php?latex=I_k&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_k' title='I_k' class='latex' /> จะมีค่าเท่ากับจำนวนสมาชิกในโหมด <img src='http://s0.wp.com/latex.php?latex=k&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='k' title='k' class='latex' /> และเราจะกล่าวว่า <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> เป็นเทนเซอร์ขนาด <img src='http://s0.wp.com/latex.php?latex=I_1+%5Ctimes+I_2+%5Ctimes+%5Cdotsb+%5Ctimes+I_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' title='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' class='latex' /></p>
<p>โดยปกติแล้วสมาชิกของเทนเซอร์แต่ละตัวจะเป็นจำนวนจริง เราใช้สัญลักษณ์ <img src='http://s0.wp.com/latex.php?latex=%5Cmathbb%7BR%7D%5E%7BI_1+%5Ctimes+I_2+%5Ctimes+%5Cdotsb+%5Ctimes+I_N%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathbb{R}^{I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N}' title='&#92;mathbb{R}^{I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N}' class='latex' /> แทนเซตของเทนเซอร์ขนาด <img src='http://s0.wp.com/latex.php?latex=I_1+%5Ctimes+I_2+%5Ctimes+%5Cdotsb+%5Ctimes+I_N&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' title='I_1 &#92;times I_2 &#92;times &#92;dotsb &#92;times I_N' class='latex' /> ที่สมาชิกแต่ละตัวของมันเป็นจำนวนจริง</p>
<blockquote><p><strong>ตัวอย่าง 1:</strong> ให้ <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> เป็นเทนเซอร์ขนาด <img src='http://s0.wp.com/latex.php?latex=2+%5Ctimes+2+%5Ctimes+2&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='2 &#92;times 2 &#92;times 2' title='2 &#92;times 2 &#92;times 2' class='latex' /> เราจะได้ว่า <img src='http://s0.wp.com/latex.php?latex=%5Cmathcal%7BA%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='&#92;mathcal{A}' title='&#92;mathcal{A}' class='latex' /> ประกอบด้วยสมาชิก 8 ตัวคือ <img src='http://s0.wp.com/latex.php?latex=a_%7B111%7D%2C+a_%7B112%7D%2C+a_%7B121%7D%2C+a_%7B122%7D%2C+a_%7B211%7D%2C+a_%7B212%7D%2C+a_%7B221%7D%2C&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{111}, a_{112}, a_{121}, a_{122}, a_{211}, a_{212}, a_{221},' title='a_{111}, a_{112}, a_{121}, a_{122}, a_{211}, a_{212}, a_{221},' class='latex' /> และ <img src='http://s0.wp.com/latex.php?latex=a_%7B222%7D&amp;bg=ffffff&amp;fg=333333&amp;s=0' alt='a_{222}' title='a_{222}' class='latex' /></p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pramook.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pramook.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pramook.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pramook.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pramook.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pramook.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pramook.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pramook.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pramook.wordpress.com&amp;blog=8520422&amp;post=3&amp;subd=pramook&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pramook.wordpress.com/2009/07/10/tensor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcaa436246bdf7f7fd17e639abbf0baa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cardcaptor</media:title>
		</media:content>
	</item>
	</channel>
</rss>
