<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nerd Rage</title>
	<atom:link href="http://www.marcuswinter.de/feed" rel="self" type="application/rss+xml" />
	<link>http://www.marcuswinter.de</link>
	<description>the blog of Marcus Winter</description>
	<lastBuildDate>Thu, 16 May 2013 09:04:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>the math of bokeh</title>
		<link>http://www.marcuswinter.de/archives/1703</link>
		<comments>http://www.marcuswinter.de/archives/1703#comments</comments>
		<pubDate>Sat, 11 May 2013 19:18:22 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[photography]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1703</guid>
		<description><![CDATA[If you don’t know (yet) what bokeh is, check out the Wikipedia article. In short, bokeh is the blur (or quality thereof) of out-of-focus regions in a photograph. This post is not about the perceived quality of such blur, but rather of its size. For bokeh, more is usually better, since it allows to separate [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />If you don’t know (yet) what bokeh is, check out the <a href="http://en.wikipedia.org/wiki/Bokeh" target="_blank">Wikipedia article</a>. In short, bokeh is the blur (or quality thereof) of out-of-focus regions in a photograph. This post is not about the perceived quality of such blur, but rather of its size. For bokeh, more is usually better, since it allows to separate an object in focus nicely from the blurred background. For the calculations that follow, we will look at the size of the image of point originating far behind an object of interest in the picture. To make the calculations easier, that point is assumed to be infinitely far away – the difference to points which are finitely but significantly far behind the object will be negligible.</p>
<div class="wp-caption aligncenter" style="width: 510px"><img src="/media/1703_20090327-08806.jpg" width="500" height="333" class /><p class="wp-caption-text">Bokeh lights in San Diego’s Gaslamp Quarter, taken with a Sony DSC-R1 at 69.8mm with f/4.8 and focused to the near limit of about 50cm.</p></div>
<h4>Basics</h4>
<p>The disks in Figure 1 are essentially the images of point sources located a long distance away and are used here to illustrate the bokeh effect. In a “regular” photograph, each point in the background of the scene is convolved with the shape of the bokeh disk and superposed with the disks from all other background points, just like the overlapping disks in Figure 1. The result is a more or less blurred background which nicely isolates an in-focus foreground. The larger the bokeh disk, the more pronounced the blur effect and foreground isolation will be. For lots of great examples, check out <a href="http://www.flickr.com/groups/bokeh_/pool/" target="_blank">flickr’s <em>Bokeh - Smooth &amp; Silky</em> picture pool</a>.</p>
<p>Calculating the expected size of bokeh disks – and thus the strength of the bokeh effect – is not at all that hard. The only formula from optics that we need is the <em>thin lens formula</em></p>
<p>$$\frac{1}{f} = \frac{1}{a} + \frac{1}{b} \tag{1}$$</p>
<p>where $f$ is the focal length of the lens, $a$ is the object distance, and $b$ is the image distance. The rest is just basic trigonometry. We will assume a thin lens throughout to make our life easier. However, the results then will only hold for $a \gg f$, since otherwise the geometry of the lens becomes relevant. Therefore, macro photography is not covered by this post.</p>
<p>The above quantities and a few more are shown in Figure 2. Here, $\Delta b$ is the difference in image distance between an object at distance $a$ and one at infinity, as can be determined using (1) – for the object at infinity, $b = f$. Furthermore, $A$ is the (absolute) aperture size of the lens, as related to its f-number $N_f$ by $A = f / N_f$, $w$ is the size of the sensor, and $d$ is the diameter of the bokeh disk on the sensor.</p>
<div class="wp-caption aligncenter" style="width: 510px"><a href="/media/1703_basics.png"><img src="/media/1703_basics.png" width="450" class /></a><p class="wp-caption-text">Figure 2: Basic quantities for bokeh calculations:<br />
$a$ - object distance<br />
$b$ - image (sensor) distance<br />
$f$ - focal length<br />
$A$ - lens aperture<br />
$w$ -sensor size<br />
$d$ - size of bokeh disk</p></div>
<p><span id="more-1703"></span></p>
<p>Now from Figure 2 we have (red ray)</p>
<p>$$d = \Delta b \frac{A}{f} = \frac{\Delta b}{N_f}\tag{2}$$</p>
<p>with</p>
<p>$$\Delta b = \frac{f^2}{a-f}\tag{3}$$</p>
<p>which can be obtained from (1) by setting $b = f + \Delta b$. Remember that $a \gg f$, so that actually $\Delta b \ll f$, unlike shown in the figure. Combining (2) and (3) we get</p>
<p>$$d = A \frac{f}{a-f} \tag{4}$$</p>
<p>which for $a \gg f$ can be simplified to</p>
<p>$$d \approx A \frac{f}{a} = \frac{f^2}{a N_f}\tag{5}$$</p>
<p>So, a large aperture $A$ (small f-number $N_f$) will produce large bokeh disks, as well as does a large focal length. At a constant aperture, the bokeh disk is proportional in size to the focal length; at a constant f-number, the bokeh disk sizes increases with the square of focal length. Also, the closer the object is to the lens the more blurry the bokeh will be.</p>
<h4>Stopping Down</h4>
<p>What happens when the aperture becomes smaller because the lens is “stopped down?” Figure 3 shows.</p>
<div class="wp-caption aligncenter" style="width: 510px"><a href="/media/1703_stopping-down.png"><img src="/media/1703_stopping-down.png" width="450" height="180" class /></a><p class="wp-caption-text">Figure 3: Effect of a smaller aperture.</p></div>
<p>Comparing with Figure 2, we can easily see how the bokeh disk becomes smaller because the angle of the outermost (red) rays becomes less acute as they pass through the focal point.</p>
<p>For great bokeh, your aperture cannot be large enough, i.e. your lens f-number cannot be small enough.</p>
<h4>Sensor size</h4>
<p>If you’ve ever compared a photo shot with a full-frame camera to one shot with a phone camera, you already know the result of this section. But we’ll calculate it anyway.</p>
<p>To image the same field of view (same object size for a given distance), the focal length of a camera with a smaller sensor must also be smaller, as shown in Figure 4.</p>
<div class="wp-caption aligncenter" style="width: 510px"><a href="/media/1703_sensor-size.png"><img src="/media/1703_sensor-size.png" width="450" height="221" class /></a><p class="wp-caption-text">Figure 4: Illustration of the relationship between sensor size $w$ and focal length $f$.</p></div>
<p>The field of view $\theta$ is given by</p>
<p>$$ \tan \frac{\theta}{2} = \frac{w}{2 f} \tag{6}$$</p>
<p>and for an equal field of view $\theta$ we have $w \propto f$. Hence, according to (5), $d \propto w^2$ for an equal f-number. The corresponding ray trajectories are shown in Figure 5.</p>
<div class="wp-caption aligncenter" style="width: 460px"><a href="/media/1703_small-sensor.png"><img src="/media/1703_small-sensor.png" width="450" height="184" class /></a><p class="wp-caption-text">Figure 5: Ray trajectories for a smaller sensor, leaving object distance $a$, field of view $\theta$ and f-number $N_f$ constant.</p></div>
<p>However, since the sensor is smaller, the image of the bokeh disk takes up a larger part of the whole image, and to be fair we should normalize the disk size $d$ by the sensor size $w$ in order to give the size of the bokeh disk as fraction of the whole image (which is what you will eventually see when looking at the picture). Then,</p>
<p>$$\frac{d}{w} \propto \frac{w}{a N_f} \tag{7}$$</p>
<p>Thus, the bokeh size as fraction of the whole image for a full-frame sensor will be about eight times as large as that for a 1/3.2″ sensor, as can be found in e.g. the iPhone 5, at the same f-number and field of view. More generally, the bokeh fraction scales inversely with the “crop factor” for the various sensor sizes, with APS-C having about 2/3 that of full-frame, Four-Thirds having about 3/4 that of APS-C, and so on.</p>
<p>If you simply use a lens with some focal length $f$ and f-number $N_f$ on a camera with a smaller sensor, you will get bokeh disks which are even larger than those on the large sensor (multiplied by the crop factor), but your field of view $\theta’$ becomes smaller, as also shown in Figure 4, and you might not image the object completely.</p>
<p>For great bokeh, your sensor cannot be large enough.</p>
<h4>Focal Length with Fixed Object Size</h4>
<p>When the object is to be imaged at a certain size on the sensor, we have to increase the object distance $a$ when we increase the focal length $f$. How does this affect the bokeh?</p>
<p>For an object of extent $h$ from the optical axis, we need a observation distance $a$ that depends on the field of view $\theta$ as</p>
<p>$$\tan \frac{\theta}{2} = \frac{h}{a} = \frac{w}{2f}$$</p>
<p>and thus</p>
<p>$$a = \frac{2f h}{w}$$</p>
<p>where we also used (6). Then with (5),</p>
<p>$$d\bigr|_{h = \mathrm{const}} = \frac{f w}{2h N_f} = A \frac{w}{2h} \tag{8}$$</p>
<p>If you have a zoom lens that has a constant aperture $A$ throughout the focal length range, the bokeh disk size will not change if you adjust the object distance so as to have a constant object size in the image. At a fixed f-number, however, the bokeh disk size increases with focal length, though only linearly instead of quadratically as in (5). </p>
<h4>Epilog</h4>
<p>There you have it. For a given field-of-view to be imaged, nothing beats a camera with a large sensor and a lens with a small f-number, both usually not cheap. Whether the bokeh quality is “good” or “bad” is a whole different story, though.</p>
<p>In principle, similar calculations can be used to determine the depth-of-field which is basically those distances $\Delta a_+$ and $\Delta a_-$ (instead of the infinite distance used here) at which the size of the bokeh disk has some defined value such that an imaged point is just perceived as sharp. The bokeh disk in this context is called circle of confusion. See also the <a href="http://en.wikipedia.org/wiki/Depth_of_field" target="_blank">Wikipedia article on depth of field</a> or <a href="http://toothwalker.org/optics/dof.html" target="_blank">Paul van Walree’s article on the depth of field</a> [toothwalker.org].</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1703/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Microsoft Project Lessons</title>
		<link>http://www.marcuswinter.de/archives/1699</link>
		<comments>http://www.marcuswinter.de/archives/1699#comments</comments>
		<pubDate>Sun, 07 Apr 2013 16:08:35 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[project management]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1699</guid>
		<description><![CDATA[Here are some tips for using MS Project in particular and project management in general that I picked up, which have either proven useful or which sound reasonable and which I plan to try out in the future. Feel free to add yours in the comments. Leave Buffers Since no project ever goes according to [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />Here are some tips for using MS Project in particular and project management in general that I picked up, which have either proven useful or which sound reasonable and which I plan to try out in the future. Feel free to add yours in the comments.</p>
<style type="text/css">
  TD.spanned {vertical-align: middle;}
  TR.section {border-bottom: 1px solid #888;}
  TABLE {width: 100%;}
</style>
<h4>Leave Buffers</h4>
<p>Since no project ever goes according to plan, it’s sensible to plan ahead by inserting buffers which can eat up some of the delay. Buffers shouldn’t be added to every task, but at the end of project phases or before milestones. A buffer of 15% of the phase duration was recommended in [1]. A buffer can be added by</p>
<ul>
<li>inserting a dedicated buffer task between project phases, or</li>
<li>using positive <code>Lag</code> between tasks (phases) that are dependent on another (see below), or</li>
<li>creating a <em>manually scheduled</em> summary task for the project phase to which the buffer is added. In this case MS Project separately keeps track of the subtasks’ duration whose progress bar turns red when it exceeds the summary task’s set duration.</li>
</ul>
<h4>Beware of Slack</h4>
<p>Don’t calculate with 100% productive-towards-the-project resources (people). Nobody works without distractions. This can be accounted for by</p>
<ul>
<li>setting <code>Max Units</code> of the resources to less than 100% (<code>Resource</code> sheet, <code>Max Units</code> cell), or</li>
<li>using shorter workdays in the project (<code>Project Options</code> → <code>Schedule</code>)</li>
</ul>
<p>The first option is more flexible and more visible.<br />
If you also schedule equipment resources, you can probably leave <code>Max Units</code> at 100%. Don’t use the second option in this case.</p>
<h4>Use Hyperlinks</h4>
<p>If you have documents describing a task / work package in detail, link the tasks in Project to these documents by choosing <code>Hyperlink</code> in the context menu of relevant tasks.</p>
<p><span id="more-1699"></span></p>
<h4>Understand Task Types</h4>
<p>When you make changes to a task’s duration, resource units or work, Project will calculate the other two quantities automatically according to these rules:</p>
<table id="types">
<tr class="section">
<th>Task Type</th>
<th>User Changes</th>
<th>Program Adjusts</th>
</tr>
<tr>
<td rowspan=3 class="spanned">Fixed Units</td>
<td>Duration</td>
<td>Work, based on Units</td>
</tr>
<tr>
<td>Units</td>
<td>Duration, based on Work</td>
</tr>
<tr class="section">
<td>Work</td>
<td>Duration, based on Units</td>
</tr>
<tr>
<td rowspan=3 class="spanned">Fixed Duration</td>
<td>Duration</td>
<td>Work, based on Units</td>
</tr>
<tr>
<td>Units</td>
<td>Work, based on Duration</td>
</tr>
<tr class="section">
<td>Work</td>
<td>Units, based on Duration</td>
</tr>
<tr>
<td rowspan=3 class="spanned">Fixed Work</td>
<td>Duration</td>
<td>Units, based on Work</td>
</tr>
<tr>
<td>Units</td>
<td>Duration, based on Work</td>
</tr>
<tr>
<td>Work</td>
<td>Duration, based on Units</td>
</tr>
</table>
<p>It’s a good idea to change the task type only while you are making changes to a task, and afterwards resetting it to the standard <code>Fixed Units</code> type, in order to avoid unexpected behavior and confusion in the future.</p>
<h4>Equipment is a Work Resource</h4>
<p>This may sound counter-intuitive, but material resources are consumables that are planned by quantity, not by availability. If you have two pieces of some particular equipment, set <code>Max Units</code> to 200%, and analogous for more. Equipment resources likely don’t need slack adjustment to their <code>Max Units</code> (see above).</p>
<h4>Use Task Dependencies and Lag</h4>
<p>When you use <code>Automatic Scheduling</code> (and you should), make use of the different task dependency options. These are</p>
<ul>
<li>Finish-to-Start (FS): <code>Successor</code> task starts when <code>Predecessor</code> task has finished. Most common option. Positive <code>Lag</code> creates a delay between tasks, negative <code>Lag</code> leads to overlap.</li>
<li>Start-to-Start (SS): <code>Successor</code> task starts when <code>Predecessor</code> task starts. Positive <code>Lag</code> delays the start time of the <code>Successor</code>, negative <code>Lag</code> advances it.</li>
<li>Finish-to-Finish (FF): <code>Successor</code> task finishes when <code>Predecessor</code> has finished. Positive <code>Lag</code> delays the finish time of the <code>Successor</code>, negative <code>Lag</code> advances it.</li>
<li>Start-to-Finish (SF): <code>Successor</code> task finishes when <code>Predecessor</code> task starts. Positive <code>Lag</code> leads to overlap, negative <code>Lag</code> creates a delay between tasks.</li>
</ul>
<p><code>Successor</code> and <code>Predecessor</code> merely describe the dependency (which task controls the other), not the temporal order of the tasks, which can certainly cause confusion in the SF case.<br />
<code>Lag</code> can also be entered as a percentage of the duration of <code>Predecessor</code>, which can be useful for creating buffers (see above).</p>
<p><div class="wp-caption aligncenter" style="width: 510px"><img src="/media/Project/1699_FS.png" width="310" height="94"/><p class="wp-caption-text">Finish-to-Start dependency without lag (top) and with 50% lag (bottom).</p></div><div class="wp-caption aligncenter" style="width: 510px"><img src="/media/Project/1699_SS.png" width="310" height="94"/><p class="wp-caption-text">Start-to-Start dependency without lag (top) and with 50% lag (bottom).</p></div><div class="wp-caption aligncenter" style="width: 510px"><img src="/media/Project/1699_FF.png" width="310" height="94"/><p class="wp-caption-text">Finish-to-Finish dependency without lag (top) and with 50% lag (bottom).</p></div><div class="wp-caption aligncenter" style="width: 510px"><img src="/media/Project/1699_SF.png" width="310" height="94"/><p class="wp-caption-text">Start-to-Finish dependency without lag (top) and with 50% lag (bottom).</p></div></p>
<h4>Use Summary Tasks</h4>
<p>Summary tasks are a helpful visual aid when the project is divided into different phases, each with its own set of tasks. With a single click all subtasks can be hidden from view when a particular phase is no longer relevant or when the structure of subtasks is of no current interest, e.g. individual acquisition tasks before the start of assembly.<br />
Also, changing a summary task to <code>Manually Scheduled</code> in Project adds a duration indicator for the contained subtasks as part of the task bar. Should the duration of the subtasks exceed the duration of the summary task, e.g. because of unforeseen delays, this duration indicator turns red, warning about the problem. Manual scheduling also allows for inserting some buffer time as described above by making following tasks depend on the finish of the summary task instead of a particular subtask.<br />
<div class="wp-caption aligncenter" style="width: 510px"><img src="/media/Project/1699_summary-tasks.png" width="218" height="97"/><p class="wp-caption-text">Automatically scheduled summary task (top), manually scheduled summary task with remaining buffer (middle) and with exceeded buffer (bottom).</p></div></p>
<h4>Save your Favorite Views</h4>
<p>If you find yourself using similar views over and over again, save your setting as custom view(s) and make it available to your other projects.<br />
To show e.g. a Gantt / Entry Table with custom columns and bar styles, and with the Task Details Form in a second pane below the chart, follow these steps:</p>
<ul>
<li>In the <code>View</code> ribbon, select the <code>Gantt Chart</code> view.</li>
<li>In the <code>View</code> ribbon, select <code>Data</code> → <code>Tables</code> → <code>Entry</code> (or your favorite table) and use the <code>Format</code> ribbon’s <code>Columns</code> section to format the table to your liking. Often, less (columns) is more and you can also get e.g. <code>Start</code> and <code>Finish</code> data by hovering the mouse over the task bars in the Gantt chart or in the <code>Task Details Form</code> that we’ll setup later.</li>
<li>In the <code>Format</code> ribbon use the <code>Bar Styles</code> section to format the task bars to your liking.</li>
<li>Go to <code>File</code> → <code>Info</code> → <code>Organizer</code>, select the <code>Tables</code> tab, select the appropriate table on the right side and click <code>&lt;&lt; Copy</code>. In the pop-up warning box, click <code>Rename...</code> and give the table a new name in the global template (do not first rename and then copy). Do the same with the view in the <code>Views</code> tab of the <code>Organizer</code> (as the table to use is saved in the custom view).<br />
<img src="/media/Project/1699_organizer.png" width="667" height="321" class="alignnone" /><br />
<img src="/media/Project/1699_organizer_warning.png" width="594" height="128" class="alignnone" /></li>
<li>In any of the drop-downs in the <code>View</code> ribbon, <code>Task Views</code> section, select <code>More Views...</code><br />
<img src="/media/Project/1699_more-views.png" width="326" height="253" class="aligncenter" /></li>
<li>In the dialog box, click on <code>New...</code> and select <code>Combination View</code>.<br />
<img src="/media/Project/1699_new-view.png" width="289" height="122" class="aligncenter" /></li>
<li>Give the view a new name and select your custom view for the <code>Primary View</code> and e.g. the <code>Task Details Form</code> for the <code>Details Pane</code>.<br />
<img src="/media/Project/1699_view-definition.png" width="384" height="206" class="aligncenter" /></li>
<li>Go back to the <code>Organizer</code> and copy your combination view to the global template to make it available in your other projects.</li>
</ul>
<h4>References</h4>
<p>[1] Bonnie Biafore, <em>Microsoft Project 2010: The Missing Manual</em>, O’Reilly Media, 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1699/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adventures in JavaScript: Number Bases</title>
		<link>http://www.marcuswinter.de/archives/1696</link>
		<comments>http://www.marcuswinter.de/archives/1696#comments</comments>
		<pubDate>Sun, 10 Mar 2013 18:33:04 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[mathematics]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1696</guid>
		<description><![CDATA[Here’s just a quick little JavaScript that will convert numbers between different bases. It grew out of the idea that numbers in a system based on π would be much more useful in engineering that the regular old ones. Well, just because one can do it doesn’t mean it’s a good idea, but it was [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />Here’s just a quick little JavaScript that will convert numbers between different bases. It grew out of the idea that numbers in a system based on π would be much more useful in engineering that the regular old ones. Well, just because one can do it doesn’t mean it’s a good idea, but it was fun figuring out how to best implement such a conversion. Once you know how to do it to and from one base, all other bases are trivial. That’s why there are a couple more besides π.</p>
<p>Enter a number into any field to convert it to the other bases.</p>

<style type="text/css">
	FORM#pageForm P {
		text-align: center;
	}
	FORM#pageForm INPUT {
		width: 150px;
		text-align: right;
		border: 1px solid #CCC;
		padding: 1px;
		margin: 0;
	}
TABLE#baseTable {
width: 90%;
border: 0;
}
TD.description {
width: 40%;
text-align: right;
}
</style>

<script src="/javascript/libs/jquery-1.8.2.min.js"></script>
<script src="/javascript/number-base.js" type="text/javascript"></script>


<div id="formWrapper">
<form id="pageForm" name="pageForm">
	<p>
<table id="baseTable">
<tr><td class="description">decimal:</td>
<td class="value"><input type="text" id="decimalBase" name="decimalBase" class="valueInput" value="1234"/> <span id="intTags"></span></td></tr>
<tr><td class="description">binary:</td>
<td class="value"><input type="text" id="binaryBase" name="binaryBase" class="valueInput" value=""/></td></tr>
<tr><td class="description">octal:</td>
<td class="value"><input type="text" id="octalBase" name="octalBase" class="valueInput" value=""/></td></tr>
<tr><td class="description">hexadecimal:</td>
<td class="value"><input type="text" id="hexadecimalBase" name="hexadecimalBase" class="valueInput" value=""/></td></tr>
<tr><td class="description">base π:</td>
<td class="value"><input type="text" id="piBase" name="piBase" class="valueInput" value=""/></td></tr>
<tr><td class="description">base e:</td>
<td class="value"><input type="text" id="eBase" name="eBase" class="valueInput" value=""/></td></tr>
</table>
	</p>
</form>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1696/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adventures in JavaScript: Humidity</title>
		<link>http://www.marcuswinter.de/archives/1692</link>
		<comments>http://www.marcuswinter.de/archives/1692#comments</comments>
		<pubDate>Sun, 16 Dec 2012 12:07:01 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[sundries]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1692</guid>
		<description><![CDATA[You thoroughly air out your rooms during winter time and watch the humidity inside drop in the process (provided you own a hygrometer). But where will it stop? This little gadget will tell you. Just enter the outside temperature and humidity and the temperature the air will be heated up to inside.   References [1] [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />You thoroughly air out your rooms during winter time and watch the humidity inside drop in the process (provided you own a hygrometer). But where will it stop? This little gadget will tell you. Just enter the outside temperature and humidity and the temperature the air will be heated up to inside.</p>
<p><script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: "all" } }
});
</script></p>
<p> </p>

<style type="text/css">
	FORM#humidityForm P {
		text-align: center;
	}
	FORM#humidityForm INPUT {
		width: 54px;
		text-align: right;
		border: 1px solid #CCC;
		padding: 1px;
		margin: 0;
	}
	FORM#humidityForm SELECT {
		border: 1px solid #CCC;
		margin: 0;
	}
</style>

<script src="/javascript/libs/jquery-1.8.2.min.js"></script>
<script src="/javascript/humidity.js" type="text/javascript"></script>


<div id="formWrapper">
<form id="humidityForm" name="humidityForm">
	<p>
	A relative humidity of <input type="text" id="fromHumidity" name="fromHumidity" class="valueInput" value="80"/>% at a temperature of 
	<input type="text" id="fromTemperature" name="fromTemperature" class="valueInput" value="0"/>
	<select id="temperatureUnits" name="temperatureUnits" class="unitSelect">
		<option value="C" selected="selected">°C</option>
		<option value="F">°F</option>
		<option value="K">K</option>
	</select><br />
	corresponds to<br />
	a relative humidity of 
	<span id="toHumidity">22.44</span>% at a temperature of <input type="text" id="toTemperature" name="toTemperature" class="valueInput" value="20"/><span class="temperatureUnitsClass">°C</span>.<br />
	The absolute humidity is <span id="absoluteHumidity">3.878</span> g/m³.
	</p>
</form>
</div>

<h4>References</h4>
<p>[1] <a href="http://en.wikipedia.org/wiki/Humidity" title="Humidity" target="_blank">Humidity</a> [Wikipedia]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1692/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Paraxiality</title>
		<link>http://www.marcuswinter.de/archives/1689</link>
		<comments>http://www.marcuswinter.de/archives/1689#comments</comments>
		<pubDate>Wed, 28 Nov 2012 19:28:46 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[coherent optics]]></category>
		<category><![CDATA[diffraction]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1689</guid>
		<description><![CDATA[The previous post on the Gaussian beam noted that this beam is a solution to the paraxial wave equation and thus only accurate for small divergence angles. The limit given in [1] was $w_0 \gt 2\lambda/\pi$ or $\theta \lt 0.5\mathrm{rad}$ or $\approx 29^\circ$. The Gaussian beam model is of course not exact up to that [...]]]></description>
				<content:encoded><![CDATA[<p id="top" /><script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: "all" } }
});
</script></p>

<style type="text/css">
	DIV.flotPlot {
		width: 500px; height: 300px;
		font-size: 1.4em;
	}
	DIV.flotPlot TABLE {margin: 0;}
	.legendLabel {font-size: 12px; font-family: 'Droid Sans', Helvetica, Arial, sans-serif;}
	td.legendColorBox {padding-bottom: 5px;}
	.legend table {margin: 0;}
	.postbutton, .postbutton:focus {padding: 5px; margin: 0px 5px; border: 1px solid #CCC; width: 70px; display: inline-block; text-align: center; background: #888; color: white !important; overflow: visible;}
	.buttonContainer {display: block; text-align: center;}

</style>


<script src="/javascript/libs/jquery-1.8.2.min.js"></script>
<script src="/javascript/libs/flot/jquery.flot.js"></script>
<script src="/javascript/libs/flot/jquery.flot.axislabels.js" type="text/javascript"></script>
<script src="/javascript/fn-plotFigure.js" type="text/javascript"></script>
<script type="text/javascript">

$(window).load( function() { // with document.ready(), Chrome does not show axis ticks until the first redraw
	$.getJSON("/media/1689_paraxiality_cross-section.json", function(importData) {
		plotFigure([{data: importData.gaussBeam.exactMagnitude, label: "exact"}, {data: importData.gaussBeam.paraxialMagnitude, label: "paraxial"}], "graphOne", {x: "transverse position [μm]", y: "relative field amplitude"}, [0, 0.025, 0.050, 0.075, 0.100]);
		plotFigure([{data: importData.gaussBeam.exactPhase, label: "exact"}, {data: importData.gaussBeam.paraxialPhase, label: "paraxial"}], "graphTwo", {x: "transverse position [μm]", y: "field phase"}, "phase");
	});

showPlot("1.0");

});

function showPlot(waist) {
	$.getJSON("/media/1689_paraxiality_delta_w" + waist + ".json", function(importData) {
		plotFigure([{data: importData.gaussBeamNF.deltaMagnitude, label: "near field"}, {data: importData.gaussBeamFF.deltaMagnitude, label: "far field"}], "graphThree", {x: "normalized transverse position r / w(z)", y: "normalized amplitude error"}, [-0.12, -0.06, 0, 0.06, 0.12]);
		plotFigure([{data: importData.gaussBeamNF.deltaPhase, label: "near field"}, {data: importData.gaussBeamFF.deltaPhase, label: "far field"}], "graphFour", {x: "normalized transverse position r / w(z)", y: "phase error"}, [[-3/2*Math.PI, "−3π/2"], [-Math.PI, "−π"], [-Math.PI/2, "−π/2"], [0, "0"], [Math.PI/2, "π/2"]]);
	});
}

</script>

<p>The <a href="http://www.marcuswinter.de/archives/1685" title="the Gaussian beam (interactive)">previous post</a> on the Gaussian beam noted that this beam is a solution to the paraxial wave equation and thus only accurate for small divergence angles. The limit given in [1] was $w_0 \gt 2\lambda/\pi$ or $\theta \lt 0.5\mathrm{rad}$ or $\approx 29^\circ$. The Gaussian beam model is of course not exact up to that limit angle and then suddenly becomes inaccurate. There actually is always a small error which grows as the divergence angle increases.</p>
<p>To get a notion of how accurate the approximation is for various beam waists, the Fourier diffraction propagation method as explained in <a href="/archives/1415">this post</a> can help, unlike the Fresnel or Fraunhofer propagation methods which were shown in <a href="/archives/1351" title="Scalar Diffraction - Huygens, Fresnel, Fraunhofer">this post</a> and which also make the paraxial approximation are thus not of great use here.</p>
<p>Using Fourier propagation on a Gaussian field distribution with $w_0 = \lambda$ in the source plane, we can compare the exact field and the Gaussian beam model at any propagation distance. This is the result at $10\lambda$ from the waist position:</p>
<div class="wp-caption aligncenter" style="width: 520px"><br />

<div id="graphOne" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Plot of the normalized transverse amplitude at longitudinal position z = 10λ from the beam waist w<sub>0</sub> = λ for the Gaussian beam (blue) and the exact field (red).</p></div>
<div class="wp-caption aligncenter" style="width: 520px"><br />

<div id="graphTwo" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Plot of the transverse phase evolution at longitudinal position $z$ = 10μm from beam waist w<sub>0</sub> = λ for the Gaussian beam (blue) and the exact field (red).</p></div>
<p>The Gaussian and exact fields differ significantly away from the optical axis. The difference between the exact and Gaussian fields is plotted below for various beam waist to wavelength ratios. Refer to <a href="http://www.marcuswinter.de/archives/1685" title="the Gaussian beam (interactive)">this post</a> to calculate any other beam parameters for these cases.</p>
<p>The amplitude error is normalized to the exact on-axis field. This way the errors at different distances remain comparable without giving undue significance to the weak fields far away from the axis. The phase difference is not normalized. All plots show a transverse cross section of the beam up to a radius of $2 w(z)$ as computed from the Gaussian beam model.</p>
<p><span id="more-1689"></span></p>
<p>Click on the buttons to see the results for the respective beam:<br />
<span class="buttonContainer"><a class="postbutton" href="javascript:showPlot('0.5');">w<sub>0</sub> = λ/2</a><a class="postbutton" href="javascript:showPlot('0.6366');">w<sub>0</sub> = 2λ/π</a><a class="postbutton" href="javascript:showPlot('1.0');">w<sub>0</sub> = λ</a><a class="postbutton" href="javascript:showPlot('2.0');">w<sub>0</sub> = 2λ</a></span></p>
<div class="wp-caption aligncenter" style="width: 520px"><br />

<div id="graphThree" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Amplitude difference between (paraxial) Gaussian beam and exact field, normalized to the on-axis field, vs. transverse position for the near field at $z$ = λ (red) and the far field at $z = 10 z_R$ (blue).</p></div>
<div class="wp-caption aligncenter" style="width: 520px"><br />

<div id="graphFour" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Phase difference between (paraxial) Gaussian beam and exact field vs. transverse position for the near field at $z$ = λ (red) and the far field at $z = 10 z_R$ (blue).</p></div>
<p>Clearly, the validity limit $w_0 = 2\lambda/\pi$ for the Gaussian beam model already has a significant phase error in the far field, which could be relevant for mode coupling calculations. This should be kept in mind before blindly trusting such calculations.</p>
<h4>References</h4>
<p>[1] <a href="http://en.wikipedia.org/wiki/Gaussian_beam">Gaussian beam</a> [Wikipedia]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1689/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>the Gaussian beam (interactive)</title>
		<link>http://www.marcuswinter.de/archives/1685</link>
		<comments>http://www.marcuswinter.de/archives/1685#comments</comments>
		<pubDate>Wed, 14 Nov 2012 19:38:00 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[coherent optics]]></category>
		<category><![CDATA[mathematics]]></category>
		<category><![CDATA[physics]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1685</guid>
		<description><![CDATA[The Gaussian beam “is a convenient, widespread model in laser optics.” [1] It is indeed convenient that such a mathematically relatively simple model can describe the evolution of laser light in free space so well. Given the wavelength of the laser, it can be described by a single parameter. This can be either the beam [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />The Gaussian beam “is a convenient, widespread model in laser optics.” [1] It is indeed convenient that such a mathematically relatively simple model can describe the evolution of laser light in free space so well. Given the wavelength of the laser, it can be described by a single parameter. This can be either the beam waist $w_0$, its far-field divergence angle $\theta$ or numerical aperture $\mathrm{NA}$, the Rayleigh range $z_R$ or the confocal parameter $b$. Given one, the others are easily determined. The graphic below will aid this process. Start by entering a wavelength or frequency, and then enter any of the various parameters and the rest will be calculated.</p>
<p>Below the graphic, various plots will give the beam cross-section (amplitude, intensity and phase) and the evolution of beam width and wavefront curvature near the waist position $z=0$. At the bottom of the page, the various formulas used for the calculations here are given.</p>
<p>Also note that the Gaussian beam is a solution of the <em>paraxial Helmholtz (wave) equation</em>, i.e. it is only a good approximation as long as the divergence angle is not too large. This is the case when approximately $w_0 k &gt; 4$ or $w_0 &gt; 2\lambda / \pi$.</p>
<p><script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: "all" } }
});
</script></p>
<p> </p>

<style type="text/css">
	DIV#beamGraphic {
	  width: 804px;
	  height: 282px;
	  background-image: url("/media/gaussian-beam.png");
	  position: relative;
  	}
	INPUT {
		width: 54px;
		text-align: right;
		border: 1px solid #CCC;
		padding: 1px;
		margin: 0;
	}
	SELECT {
		border: 1px solid #CCC;
		margin: 0;
	}
	#quantitiesForm INPUT.valueInput,
	#quantitiesForm SELECT.unitSelect {
		position: absolute; 
	}
	INPUT#wavelengthValue { top: 6px; left: 277px; }
	SELECT#wavelengthUnits { top: 6px; left: 336px; }
	INPUT#frequencyValue { top: 6px; left: 435px; }
	SELECT#frequencyUnits { top: 6px; left: 494px; }
	INPUT#w0Value { top: 60px; left: 367px; }
	SELECT#w0Units { top: 60px; left: 426px; }
	INPUT#bValue { top: 230px; left: 387px; }
	SELECT#bUnits { top: 230px; left: 446px; }
	INPUT#thetaValue { top: 80px; left: 83px; }
	SELECT#thetaUnits { top: 80px; left: 142px; }
	INPUT#NAValue { top: 104px; left: 83px; }
	DIV.flotPlot {
		width: 500px; height: 300px;
		font-size: 1.4em;
	}
	DIV.flotPlot TABLE {margin: 0;}
	SELECT#zPosUnits { position: relative; left: -3px; }
	FORM#zPosForm { margin-bottom: -3em; }
</style>

<script src="/javascript/libs/jquery-1.8.2.min.js"></script>
<script src="/javascript/libs/flot/jquery.flot.js"></script>
<script src="/javascript/libs/flot/jquery.flot.axislabels.js" type="text/javascript"></script>
<script src="/javascript/gaussian-beam.js" type="text/javascript"></script>


<div id="beamGraphic">
<form id="quantitiesForm" name="quantitiesForm">
	<input type="text" id="wavelengthValue" name="wavelengthValue" class="valueInput" value="532.0"/>
	<select id="wavelengthUnits" name="wavelengthUnits" class="unitSelect">
		<option value="1e-9" selected="selected">nm</option>
		<option value="1e-6">μm</option>
		<option value="1e-3">mm</option>
		<option value="1">m</option>
	</select>
	<input type="text" id="frequencyValue" name="frequencyValue" class="valueInput" value="563.5"/>
	<select id="frequencyUnits" name="frequencyUnits" class="unitSelect">
		<option value="1">Hz</option>
		<option value="1e3">kHz</option>
		<option value="1e6">MHz</option>
		<option value="1e9">GHz</option>
		<option value="1e12" selected="selected">THz</option>
	</select>
	<input type="text" id="w0Value" name="w0Value" class="valueInput" value="1.000"/>
	<select id="w0Units" name="w0Units" class="unitSelect">
		<option value="1e-9">nm</option>
		<option value="1e-6" selected="selected">μm</option>
		<option value="1e-3">mm</option>
		<option value="1">m</option>
	</select>
	<input type="text" id="bValue" name="bValue" class="valueInput" value="11.81"/>
	<select id="bUnits" name="bUnits" class="unitSelect">
		<option value="1e-9">nm</option>
		<option value="1e-6" selected="selected">μm</option>
		<option value="1e-3">mm</option>
		<option value="1">m</option>
	</select>
	<input type="text" id="thetaValue" name="thetaValue" class="valueInput" value="0.1693"/>
	<select id="thetaUnits" name="thetaUnits" class="unitSelect">
		<option value="0.0174532925">deg</option>
		<option value="1" selected="selected">rad</option>
	</select>
	<input type="text" id="NAValue" name="NAValue" class="valueInput" value="0.1685"/>
</form>
</div>

<p> </p>
<p><span id="more-1685"></span></p>
<p>
<form id="zPosForm" name="zPosForm">
	<p>
	Show cross-sections for distance $z=$ <input type="text" name="zPosValue" id="zPosValue" class="valueInput" value="0"/>
	<select id="zPosUnits" name="zPosUnits" class="unitSelect">
		<option value="1e-9">nm</option>
		<option value="1e-6" selected="selected">μm</option>
		<option value="1e-3">mm</option>
		<option value="1">m</option>
	</select> from beam waist.
	</p>
</form>
<br />
<div class="wp-caption aligncenter" style="width: 510px"><br />

<div id="fieldCrosssection" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Plots of the normalized transverse amplitude $|E / E_0|$ (red) and intensity $I / I_0$ (blue) evolution at longitudinal position $z$ = <span class='zPosOutput'>0μm</span> from beam waist. The horizontal line indicates the $1/e$ amplitude, respective $1/e^2$ intensity level.</p></div></p>
<div class="wp-caption aligncenter" style="width: 510px"><br />

<div id="phaseCrosssection" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Plot of the transverse phase evolution at longitudinal position $z$ = <span class='zPosOutput'>0μm</span> from beam waist.</p></div>
<div class="wp-caption aligncenter" style="width: 510px"><br />

<div id="curvatureEvolution" class="flotPlot"></div>
<br />
<p class="wp-caption-text">Plots of the longitudinal evolution of beam width $w(z)$ and radius of wavefront curvature $R(z)$ for the Gaussian beam defined above. The vertical line denotes the Rayleigh range $z_R$.</p></div>
<h4>Formulae</h4>
<p>The complex electric field amplitude is given by [1]</p>
<p>\begin{equation}<br />
E(\mathbf{r}, z) = E_0 \frac{w_0}{w(z)} \exp \left( -\frac{\mathbf{r} \cdot \mathbf{r}}{w^2(z)} -ikz -ik \frac{\mathbf{r} \cdot \mathbf{r}}{2R(z)} +i \zeta(z) \right)<br />
\end{equation}</p>
<p>with transverse coordinate $\mathbf{r} = (x,y)^T$ and longitudinal coordinate $z$, defined such that the location of minimal beam width is at $z=0$. The quantity $k = 2\pi / \lambda$ is called the wavenumber.</p>
<p>The (time-averaged) intensity of the beam is then given by</p>
<p>\begin{equation}<br />
I(\mathbf{r},z) =  \frac{ E(\mathbf{r},z) E^*(\mathbf{r},z)}{2 \eta}  = I_0 \left( \frac{w_0}{w(z)} \right)^2 \exp \left( -\frac{2 \mathbf{r} \cdot \mathbf{r}}{w^2(z)} \right)<br />
\end{equation}</p>
<p>where $*$ denotes the complex conjugate, and $\eta$ is the characteristic impedance of the medium. The initial amplitude and intensity are</p>
<p>\begin{equation*}<br />
E_0 = E(x=0,y=0,z=0) \quad \text{and} \quad I_0 = I(x=0,y=0,z=0)<br />
\end{equation*}</p>
<p>respectively. The $1/e$ beam width is given by</p>
<p>\begin{equation}\label{beam-width}<br />
w(z) = w_0 \, \sqrt{ 1+ {\biggl( \frac{z}{z_R} \biggr)}^2 } = w_0 \, \sqrt{ 1+ {\biggl( \frac{2 z}{k w_0^2} \biggr)}^2 }<br />
\end{equation}</p>
<p>where</p>
<p>\begin{equation}\label{rayleigh-range}<br />
z_R = \frac{\pi w_0^2}{\lambda} = \frac{k w_0^2}{2}<br />
\end{equation}</p>
<p>is called the Rayleigh range and $w_0 = w(0)$ is the minimum beam width, or beam waist. At the Rayleigh range, $w(\pm z_R) = \sqrt{2} w_0$.</p>
<p>The wavefront curvature $R(z)$ is given by</p>
<p>\begin{equation}\label{curvature}<br />
R(z) = z \left[{ 1+ {\biggl( \frac{z_R}{z} \biggr)}^2 } \right] = z \left[{ 1+ {\biggl( \frac{k w_0^2}{2 z} \biggr)}^2 } \right]<br />
\end{equation}</p>
<p>At the waist, the wavefronts are plane, $R(0) = \infty$; the curvature radius decreases to a minimum at the Rayleigh range, and far from $z_R$ increases again as $R(z) \approx z$.</p>
<p>The confocal parameter, or depth of focus, $b$ is the distance between the Rayleigh ranges on both sides of the waist,</p>
<p>\begin{equation}<br />
b = 2 z_R = k w_0^2<br />
\end{equation}</p>
<p>The longitudinal phase delay $\zeta(z)$, or Guoy phase, is</p>
<p>\begin{equation}\label{guoy}<br />
\zeta(z) = \mathrm{arctan} \left( \frac{z}{z_R} \right) = \mathrm{arctan} \left( \frac{2 z}{k w_0^2} \right)<br />
\end{equation}</p>
<p>which imposes an additional phase shift of π on the beam as it passes through the focus.</p>
<p>The far-field divergence angle $\theta$ (in radians) of the beam is given by</p>
<p>\begin{equation}\label{divergence-angle}<br />
\theta \simeq \frac{\lambda}{\pi w_0} = \frac{2}{k w_0} = \frac{w_0}{z_R}<br />
\end{equation}</p>
<p>and the numerical aperture is</p>
<p>\begin{equation}<br />
\mathrm{NA} = \sin \left(\theta \right)<br />
\end{equation}</p>
<p>At the waist, the Gaussian beam is a plane wave with a Gaussian apodization, while in the far-field it is a spherical wave, also with Gaussian apodization, making it cone-shaped.</p>
<h4>Canonical Forms</h4>
<p>Interestingly, all spatial quantities in the above formulas scale with wavelength, even if it’s not immediately apparent. Hence, we can normalize the equations describing the properties of the Gaussian beam to the wavelength of the radiation to obtain the canonical, or standard, or normalized forms. Starting with the normalized quantities</p>
<p>\begin{equation*}<br />
z’ = 2\pi \frac{z}{\lambda} = k \cdot z \quad \mathbf{r}’ = k \cdot \mathbf{r} \quad w’_0 = k \cdot w_0<br />
\end{equation*}</p>
<p>we obtain from $\eqref{rayleigh-range}$ </p>
<p>\begin{equation*}<br />
z’_R = k \cdot z_R = \frac{k^2 w_0^2}{2} = \frac{{w^\prime_0}^2}{2}<br />
\end{equation*}</p>
<p>and from $\eqref{beam-width}$ and $\eqref{curvature}$</p>
<p>\begin{gather*}<br />
w’(z’) = k \cdot w\biggl(z = \frac{z’}{k}\biggr) = w’_0 \, \sqrt{ 1+ {\biggl( \frac{2 z’}{{w’_0}^2} \biggr)}^2 } \\<br />
R’(z’) = k \cdot R\biggl(z = \frac{z’}{k}\biggr) = z’ \left[{ 1+ {\biggl( \frac{{w’_0}^2}{2 z’} \biggr)}^2 } \right]\\<br />
\end{gather*}</p>
<p>Also, from $\eqref{divergence-angle}$ and $\eqref{guoy}$</p>
<p>\begin{gather*}<br />
\theta \simeq \frac{2}{w’_0} = \frac{w’_0}{z’_R}\\<br />
\zeta’(z’) = \zeta\biggl(z = \frac{z’}{k}\biggr) = \mathrm{arctan} \left( \frac{2 z’}{{w’_0}^2} \right)<br />
\end{gather*}</p>
<p>Note that since $\zeta’$ is not a coordinate or length, it does not scale with $k$ – it is simply the Guoy phase written in terms of $z’$.<br />
Then finally, the canonical form of the complex field amplitude is</p>
<p>\begin{equation*}<br />
E(\mathbf{r’}, z’) = E_0 \frac{w’_0}{w’(z’)} \exp \left( -\frac{\mathbf{r’} \cdot \mathbf{r’}}{{w’}^2(z’)} -iz’ -i \frac{\mathbf{r’} \cdot \mathbf{r’}}{2R’(z’)} + i \zeta’(z’) \right)<br />
\end{equation*}</p>
<p>and analogously the beam intensity.</p>
<h4>Notes</h4>
<p>Also check out <a href="http://www.marcuswinter.de/archives/1689" title="Paraxiality">post #145</a> which takes a closer look at the difference between the Gaussian beam model and the real beam resulting from diffraction.</p>
<h4>References</h4>
<p>[1] <a href="http://en.wikipedia.org/wiki/Gaussian_beam" title="Gaussian beam" target="_blank">Gaussian beam</a> [Wikipedia]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1685/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TiddlyWiki – EditSectionPlugin Keyboard Shortcuts</title>
		<link>http://www.marcuswinter.de/archives/1681</link>
		<comments>http://www.marcuswinter.de/archives/1681#comments</comments>
		<pubDate>Thu, 08 Nov 2012 18:34:44 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[TiddlyWiki]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1681</guid>
		<description><![CDATA[Like so many of his plugins, Eric Shulman’s EditSectionPlugin for TiddlyWiki is quite awesome. Especially in long tiddlers it can save you a lot of scrolling and searching. One thing I was missing, though, were the keyboard shortcuts ESC to cancel editing and CTRL+ENTER to finish editing, like the ones you have when editing the [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />Like so many of his plugins, Eric Shulman’s <a href="http://www.TiddlyTools.com/#EditSectionPlugin">EditSectionPlugin</a> for <a href="http://tiddlywiki.com/">TiddlyWiki</a> is quite awesome. Especially in long tiddlers it can save you a lot of scrolling and searching. One thing I was missing, though, were the keyboard shortcuts ESC to cancel editing and CTRL+ENTER to finish editing, like the ones you have when editing the full tiddler. So I added them.</p>
<p>Since the plugin code is quite long, I will just post the few lines that need to be patched / added to Eric’s original plugin. My additions are shown in red. They are based on v1.8.1 of the EditSectionPlugin.</p>

<style>
    SPAN.codeHighlight {color: #C00}
</style>

<p>In <code>config.macros.editSection.createPanel</code> add</p>
<pre class="MATLAB">
this.showPanel(p,here,ev);
<span class="codeHighlight">jQuery(f).find("INPUT[value=cancel]").focus();</span>
return this.ok(ev);
</pre>
<p>In <code>config.macros.editSection.initForm</code> add</p>
<pre class="MATLAB">
form.content.value=store.getTiddlerText(tid,''); 
<span class="codeHighlight">jQuery(form).keydown( function(eventObject) {
    if (eventObject.which == 27) { // ESC
        config.macros.editSection.cancel(jQuery(this).find("INPUT[value=cancel]").get(0),eventObject);
    }
    if (eventObject.which == 13 &#038;& eventObject.ctrlKey) { // CTRL-ENTER
        config.macros.editSection.saveForm(jQuery(this).find("INPUT[value=save]").get(0),eventObject);
    }
});</span>
if (version.extensions.TextAreaPlugin) new window.TextAreaResizer(form.content);
</pre>
<p>In <code>.initForm</code> a keyboard event handler is added to pop-up (form) that fires a function on every keypress, which listens specifically for ESC or CTRL+ENTER. When ESC is pressed, the “Cancel” button is passed to the <code>.cancel</code> function as originating element. Same with the “Save” button for CTRL-ENTER. The new line in <code>.createpanel</code> initially gives focus to the “Cancel” button (any form element would do), so that pressing e.g. ESC works without having a form element first.</p>
<p>The code could have been more concise with some changes to the <code>EditSectionTemplate</code>, but that would require editing two tiddlers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1681/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Coupon (Sticker) Collector</title>
		<link>http://www.marcuswinter.de/archives/1677</link>
		<comments>http://www.marcuswinter.de/archives/1677#comments</comments>
		<pubDate>Sat, 06 Oct 2012 16:14:53 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[mathematics]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1677</guid>
		<description><![CDATA[Supermarket chain Edeka currently runs this sticker collecting racket – which used to be smurf collecting – where you get four stickers with animal pictures for every €10 spent. The kids are collecting like crazy, I am told, even though the pictures are mediocre at best. Anyway, as geeks we don’t care much about the [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />Supermarket chain Edeka currently runs this sticker collecting racket – which used to be smurf collecting – where you get four stickers with animal pictures for every €10 spent. The kids are collecting like crazy, I am told, even though the pictures are mediocre at best. Anyway, as geeks we don’t care much about the pictures but rather the combinatorics and probability laws that make this scheme so successful.</p>
<p><script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: "all" } }
});
</script></p>

<style type="text/css">
	#collectedProbability, #meanCollectedProbability, #fullSetCDF {height: 300px; width: 500px; margin: 0 auto;}
	.legendLabel {font-size: 12px; font-family: 'Droid Sans', Helvetica, Arial, sans-serif;}
	td.legendColorBox {padding-bottom: 5px;}
	.legend table {margin: 0;}
	.postbutton, .postbutton:focus {padding: 5px; margin: 0px 5px; border: 1px solid #CCC; width: 30px; display: inline-block; text-align: center; background: #888; color: white !important; overflow: visible;}
	.buttonContainer {display: block; text-align: center;}
</style>

<h4>Expectations</h4>
<p>The simplest quantity to calculate is the expected number of stickers needed to have a full collection of all $m$ stickers (for the current Edeka campaign there are $m$ = 180 different stickers). Presumably, the stickers are randomly drawn from a set $M=\bigl\lbrace 1,2,\ldots,m\bigr\rbrace$ with uniform probability (each sticker is equally probable), where we simply assign a number for each unique sticker instead of writing out the animal names. We also neglect the fact that the stickers come in packs of four – this will affect the probabilities slightly as the packs are randomly mixed but will likely not contain doubles.</p>
<p>The probability distribution of the number of (Bernoulli) draws necessary to obtain a “success” given success probability $p_i$ is given by the geometric distribution [1]. Here, success is defined as obtaining a new sticker not yet within the collection. This probability $p_i$ reduces with each new sticker obtained. It is obviously 1 in the first draw, but the second sticker drawn will be new only with probability $m-1\big/m$ since there are only $m-1$ stickers new out of the $m$ total. Generally,</p>
<p>$$p_i = \frac{m-\bigl(i-1\bigr)}{m} \quad \text{for} \quad i\in\bigl\lbrace 1,2,…,m \bigr\rbrace \label{geometric-probability}$$</p>
<p>The total number of stickers drawn, $n_\Sigma$, is then just the sum of the number $n_i$ of stickers drawn until success $i$:</p>
<p>$$n_\Sigma = \sum\limits_{i=1}^{m} n_i \label{n_Sigma}$$</p>
<p>The expected value of the geometric distribution is the inverse of $p_i$, and since the expectation of a sum is just the sum of expectations,</p>
<p>$$\mathcal{E}\Bigl[n_\Sigma\Bigr] = \sum\limits_{i=1}^{m} \frac{1}{p_i} = \sum\limits_{i=1}^{m} \frac{m}{m-\bigl(i-1\bigr)} \label{expected-necessary-draws}$$</p>
<p>For the $m$ = <span class="totalItems">180</span> animal stickers this means that <strong>we need to collect approximately <span class="meanItems">1039</span> stickers on average to have the full set</strong>.</p>
<p>Deriving the distribution of $N$ is somewhat more difficult, since it involves the convolution of $m$ probability distributions (alternatively, multiplication of $m$ probability-generating functions with subsequent inverse z-transform of the result).</p>
<p><span id="more-1677"></span></p>
<h4>Combinatorics</h4>
<p>A different way to calculate the various probabilities and their distributions is from a combinatorical point-of-view. To find the probability of $j$ stickers missing (out of $m$ possible) in a random draw of $n$ stickers – or alternatively, the probability of $r=m-j$ different stickers being present in a drawn sample – it is sufficient to find the number of different draws of $n$ stickers in which exactly $j$ stickers are missing and normalize it by the total number of possible samples. The latter is simply $m^n$.</p>
<p>To find the number of possible draws with exactly $j$ stickers missing, we can determine the number of possible draws of $n$ stickers which contain all stickers from a reduced set of size $m-j$ and multiply then this by the number of combinations of the $j$ missing stickers (since we do not care which stickers are missing). This problem is very closely related to the <em>birthday problem</em> in which we’d like to know how many different birthdays occur on average in a group of $n$ people. For the birthday problem, $m=365$ discounting leap years. The birthday problem is very well explained and its combinatorics derived in [2] (see item 13 for the derivation of the most interesting quantity). The probability of exactly $j$ stickers missing out of a set $M$ of size $m$ in a random draw of $n$ stickers is$^1$</p>
<p>$$P_\text{missing}(j,m,n) = \binom{m}{j} \sum\limits_{k=0}^{m-j} (-1)^k \binom{m-j}{k}\left(1 - \frac{j + k}{m}\right)^n \label{P_missing}$$<br />
with<br />
$$j \in \Bigl\lbrace\max\Bigl[m-n,0\Bigr], \ldots, m-1\Bigr\rbrace \notag$$</p>
<p>since there have to be at least $m-n$ stickers missing if $n\lt m$. The probability mass function for the number $r=m-j$ of collected stickers out of $m$ total after $n$ draws (which is also given by $P_\text{missing}(j,m,n)$) is shown below.</p>
<div class="wp-caption aligncenter" style="width: 510px"><br />

<div id="collectedProbability"></div>
<br />
<p class="wp-caption-text">Probability mass function for the number of unique stickers obtained after randomly collecting $n$ stickers. The total number of different stickers available is $m$ = <span class='totalItems'>180</span>.</p></div>
<p>Interestingly, the spread of this distribution is not very large; the number of unique stickers one can expect to own at pretty much any one point does not vary much. By calculating the distribution for every $n$ we can plot the expected number of unique stickers over $n$:</p>
<div class="wp-caption aligncenter" style="width: 510px"><br />

<div id="meanCollectedProbability"></div>
<br />
<p class="wp-caption-text">Average number of unique stickers obtained vs. total number of stickers collected with $m$ = <span class='totalItems'>180</span> different stickers available (blue line). Also shown is the 10–90 percentile range (yellow bars).</p></div>
<h4>A Full Set</h4>
<p>So, then, how many stickers to we need to collect to achieve $j=0$ (a full set) with some probability $p$? This can be determined with the help of $\eqref{P_missing}$ by noting that in order to complete the collection on the $n$th sticker, there must have been one sticker missing on the $n-1$th draw. The probability of this case is $P_\text{missing}(1,m,n-1)$ and the probability of getting the missing sticker on the $n$th draw is $1/m$ as in $\eqref{geometric-probability}$, so that the probability of having the full set of stickers after exactly $n$ draws is</p>
<p>$$P_\text{full}(m,n) = \sum_{k=0}^{m-1} (-1)^k \binom{m - 1}{k} \left(1 - \frac{1+k}{m}\right)^{n-1}$$<br />
with<br />
$$n \in \Bigl\lbrace m, m + 1, \ldots \Bigr\rbrace\notag$$</p>
<p>This is the probability mass function (PMF) for $n_\Sigma$ as defined earlier in $\eqref{n_Sigma}$. The probability of having a complete set after $n_\Sigma$ draws also includes the probabilities of having completed the set on an earlier draw, so we simply integrate the PMF to obtain the cumulative density function:</p>
<div class="wp-caption aligncenter" style="width: 510px"><br />

<div id="fullSetCDF"></div>
<br />
<p class="wp-caption-text">Probability of having a full set of stickers vs. number of stickers collected so far with $m$ = <span class='totalItems'>180</span> different stickers available.</p></div>
<p>Fortunately, there are swap meets and places like eBay, or a lot of mommies would need to spend loads of money at Edeka (which I assume is the whole purpose of this exercise) – to get the 1039 stickers needed (on average) means spending about €2,600 in the supermarket chain.</p>
<h4>Other Cases</h4>
<p>Unfortunately, it is not reasonably possible to make $m$ or $n$ arbitrarily variable within this page, as browser mathematics is too limited to correctly compute the desired quantities on-the-fly (a lot of almost equal numbers are added and subtracted within the sums which poses great problems for floating point calculators). So we are limited to choosing from a few pre-computed cases. Click on the buttons below to see the graphics above change accordingly.</p>
<p>Choose a value for $m$ (number of different items available):<br />
<span class="buttonContainer"><a class="postbutton" href="javascript:readData(8);">8</a><a class="postbutton" href="javascript:readData(16);">16</a><a class="postbutton" href="javascript:readData(50);">50</a><a class="postbutton" href="javascript:readData(100);">100</a><a class="postbutton" href="javascript:readData(180);">180</a> <a class="postbutton" href="javascript:readData(210);">210</a></span></p>
<hr />
<p>Footnotes:<br />
<strong>1</strong> As of October 5, 2012 the formula given in [2] has the index of the sum running from 1 instead of 0, which I believe is an error.</p>
<p>References:<br />
[1] <a href="http://en.wikipedia.org/wiki/Geometric_distribution">Geometric Distribution</a> [Wikipedia]<br />
[2] <a href="http://www.math.uah.edu/stat/urn/Birthday.html">The Birthday Problem</a> [University of Alabama]</p>

<script src="/javascript/libs/jquery-1.8.2.min.js"></script>
<script src="/javascript/libs/flot/jquery.flot.js"></script>
<script src="/javascript/coupon-collector.js"></script>

]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1677/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Summer of Code</title>
		<link>http://www.marcuswinter.de/archives/1655</link>
		<comments>http://www.marcuswinter.de/archives/1655#comments</comments>
		<pubDate>Fri, 31 Aug 2012 17:46:15 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1655</guid>
		<description><![CDATA[Dabbling in JavaScript has been my new pasttime for the last few weeks. After a lot of poking in the dark trying to customize my TiddlyWiki, I thought that I could use my newfound JavaScript powers to make more useful stuff. So I sat down and wrote a bunch of scripts that add features to [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />Dabbling in JavaScript has been my new pasttime for the last few weeks. After a lot of poking in the dark trying to customize my TiddlyWiki, I thought that I could use my newfound JavaScript powers to make more useful stuff. So I sat down and wrote a bunch of scripts that add features to the Internet which I found missing. I tried to integrate them all into the site layout, but most of them needed a bit more space than a blog post would allow, so they got their separate pages. The links can always be found in the footer area of each page on this site.</p>
<p><span id="more-1655"></span></p>
<p><a name="delicious"></a><br />
<h4>Delicious</h4>
<p>For those haven’t heard of it, <a href="http://www.delicious.com/">the former del.icio.us</a> was one of the first social bookmarking services around. But, as with so many promising sites that were bought by Yahoo!, it languished for years without any new features except maybe a redesign of the web site. I moved my bookmarks to <a href="http://www.pinboard.in/">Pinboard</a> a while ago. At least Pinboard seems to be actively developed. Doesn’t matter, though, because Delicious claims some 5+ million users and 180 million unique bookmarks, which makes it a great resource to tap.</p>
<p>That’s where this JavaScript comes in: A feature I have been missing right from the beginning is a meaningful way to find bookmarks that are as similar as possible to any given site. Which would certainly be possible for Delicious given their vast database of URLs and tags. Sure, you can get a list of other sites with a certain tag or tag combination, or even a page listing users who have bookmarked this site and the tags they have given it. But this takes a lot of clicking, often with little result. So why not automate the process?</p>
<p>Enter a URL and the script grabs up to 100 (Delicious’ limit) public bookmarks for that site, along with user names and tag information. Getting that user list is crucial to finding like-minded people. Then you can select any of the tags that any of the users have assigned and the script will load other bookmarks from the respective users with those tags. Getting sites which have been tagged with the same tags from the same users as your URL is probably the closest you can come to finding related content. So give it a try:</p>
<p><a href="http://www.marcuswinter.de/delicious" title="Adventures in JavaScript: Delicious"><strong>Go to the Delicious script page.</strong></a>.</p>
<p>Note: The URL is exactly matched by Delicious, i.e. it matters if there’s a “www” at the beginning and even if there’s a closing forward slash. I found that including the slash at the end of the server address usually finds more bookmarks.</p>
<p><a name="sunrise"></a><br />
<h4>Sunrise</h4>
<p>This was actually the first JavaScript applet I made. Since I learned a lot while writing the <a href="http://www.marcuswinter.de/archives/1655" title="Adventures in JavaScript: Delicious">Delicious script</a>, I thought that this script could use a bit more polish before posting. Just making better use of <a href="http://jquery.com/">jQuery</a> got rid of a whole bunch of unnecessary code.</p>
<p>The script came about because I wanted to try out the <a href="https://developers.google.com/maps/documentation/javascript/">Google Maps API</a> - there are so many awesome sites and mash-ups out there that use Google Maps that I figured it can’t be that hard. And it isn’t.</p>
<p>The script uses the Google Maps <a href="https://developers.google.com/maps/documentation/javascript/geocoding">Geocoder</a> to convert a place name into latitude / longitude coordinates and then plugs these coordinates into the <a href="http://en.wikipedia.org/wiki/Sunrise_equation">sunrise equation</a> [Wikipedia] to get the sunrise and sunset times for any day. After figuring out what a Julian date is and why astronomers use this instead of regular old dates, I thought to myself that the script might as well compute the times for all days of the year. This of course would only look good in a plot, not so much in a table. A quick search turned up <a href="http://www.flotcharts.org/">Flot</a>, a quite powerful JavaScript plotting library. All this actually worked pretty well, at least for local places. However, since JavaScript lacks methods to convert UTC times (in which the sunrise time is computed) to timezones other than the user’s, more tinkering was necessary to get the sunrise in local time (and accounting for daylight savings time) in other places around the world. With <a href="https://github.com/mde/timezone-js">timezone-JS</a> [GitHub] the conversion is possible, but it needs to know what timezone to use. And Google’s geocoding doesn’t provide that. However, <a href="http://developer.yahoo.com/geo/placefinder/">Yahoo! PlaceFinder</a>’s Geocoding not only return latitude / longitude, but also the timezone in the correct IANA format. However, the Yahoo! API is completely different, as you have to perform AJAX JSON requests to the server – which I had no idea how to do yet – instead of just calling some function in a JavaScript library. In time it worked, though. After a lot of tweaking and debugging for weird places like those above the polar circle that have days without sunrise and days without sunsets (try entering Tromsø, Norway), the script started producing pretty neat graphs.</p>
<p><a href="http://www.marcuswinter.de/sunrise" title="Adventures in JavaScript: Sunrise"><strong>Go to the Sunrise script page.</strong></a></p>
<p>Update: I retrofitted the oh-so-useful autocomplete feature of the <a href="https://developers.google.com/maps/documentation/javascript/places">Google Maps Places library</a>, which is also used in other scripts, to the location input field. So now there is some Google Maps code here after all.</p>
<p><a name="elevation"></a><br />
<h4>Elevation</h4>
<p>These scripts finally make some use of the <a href="https://developers.google.com/maps/documentation/javascript/">Google Maps JavaScript API</a>, my main intent for starting with this JavaScript business after all. The area around where I live being quite hilly, I was curious about the height profiles of my biking or walking trips. The Google Maps website doesn’t give this information, and other sites like <a href="http://www.gmap-pedometer.com/">GMap Pedometer</a>, which inspired this script (and which has a host of other features useful to a lot of people), do show a height profile, but don’t compute the cumulate climb heights – which was the number I was interested in most.</p>
<p>Much of it is adapted from <a href="https://developers.google.com/maps/documentation/javascript/examples/">Google Maps API examples</a>, with some event tracking and corresponding updates. <a href="http://www.flotcharts.org/">Flot</a> is again used for plotting.</p>
<p>There are two versions of the script: One lets you enter an origin and a destination location, with full-featured Google Maps pathfinding in between.</p>
<p><a href="http://www.marcuswinter.de/route-elevation" title="Adventures in JavaScript: Route Elevation"><strong>Go to the Route Elevation script page.</strong></a></p>
<p>The other will ask for an origin location and then lets you set arbitrary waypoints, with Google Maps calculating the route between waypoints. This is useful for round trips as are typical for joggers.</p>
<p><a href="http://www.marcuswinter.de/jogging-elevation" title="Adventures in JavaScript: Jogging Elevation"><strong>Go to the Jogging Elevation script page.</strong></a></p>
<p><a name="weather-history"></a><br />
<h4>Weather History</h4>
<p>I can never remember what the weather was like in the past. Did we have a nice summer last year? Was it a cold winter in ’10? Beats me. But the information is out there if you look for it. And after some tinkering with the awesome Flot plotting library it can even be put into a useful form.</p>
<p>This script accesses weather data from <a href="http://www.dwd.de/">Deutscher Wetterdienst</a> – and therefore only shows German weather data – who freely make available measurement data of 78 weather stations around Germany. The data comes in text files which are loaded, parsed and then finally presented using <a href="http://www.flotcharts.org/">Flot</a>. Due to the limited space on a web page I chose to first compute weekly averages which expand to daily values for a month at a time when you hover the mouse over the plots. Luckily, Flot has some hooks to enable checking mouse position and also can freely scale the axes, allowing for the zoom effect. Even though I had the first plots up and running quite quickly, the script grew to almost 500 lines of codes before it was done.</p>
<p>To get around modern browsers’ same-origin policies which don’t let JavaScripts access files on servers other than the one serving the script itself, I also had to write a PHP proxy script (or rather assemble it from various sources on the web) which fetches the necessary files from DWD and transparently feeds them to the script.</p>
<p><a href="http://www.marcuswinter.de/weather-history" title="Adventures in JavaScript: Weather History"><strong>Go to the Weather History script page.</strong></a></p>
<h4>AutoPager for Kindle</h4>
<p>A final script helps me format pages to be sent to a Kindle, especially when they are paginated, i.e. spread out over several pages that you have to click through. The script loads all pages, collects the useful portions and puts them into a single document. To get the document into a Kindle, including tables, images and whatnot, I still use the excellent <a href="http://www.amazon.com/gp/sendtokindle/chrome">Send to Kindle extension</a> from amazon. For single-page articles this extension is all that’s needed, anyway.</p>
<p>The script is not integrated into the site design, works only for a few sites and misuses the <em>Nerd Rage</em> webserver as a proxy to get around JavaScript security restrictions, so I will not post the link at this time. If you are genuinely interested, just let me know and we can work something out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1655/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>shopping for a NAS</title>
		<link>http://www.marcuswinter.de/archives/1647</link>
		<comments>http://www.marcuswinter.de/archives/1647#comments</comments>
		<pubDate>Thu, 02 Aug 2012 20:54:40 +0000</pubDate>
		<dc:creator>Marcus</dc:creator>
				<category><![CDATA[sundries]]></category>

		<guid isPermaLink="false">http://www.marcuswinter.de/?p=1647</guid>
		<description><![CDATA[So I have this internal 500GB HDD drive that holds the backup for my personal data and photos and whatnot. Not only is it 98 percent full, but also very noisy, even when spinning idly. Since some Windows process always seems to access it regularly, it also never spins down. To get some peace of [...]]]></description>
				<content:encoded><![CDATA[<p id="top" />So I have this internal 500GB HDD drive that holds the backup for my personal data and photos and whatnot. Not only is it 98 percent full, but also very noisy, even when spinning idly. Since some Windows process always seems to access it regularly, it also never spins down. To get some peace of mind, I started looking at external drives that I could just switch off when the backup itself wasn’t running. However, while scouring the market I quickly realized that for a little more money I could get a drive that attaches to the home network and – for starters – could also serve as extended storage for the laptop as well as a DLNA media server for the TV. These devices are commonly called network attached storage (NAS).</p>
<p>While looking for enlightening reviews I noticed that there were quite a few consumer / SOHO devices out there and if I wanted a device that I’d be happy with for the next couple of years I need to go about finding it in a more systematic way. Serendipitously, I remembered the concept of decision matrices from an earlier life, which are perfect for this kind of thing while at the same time being very straightforward.</p>
<p>Along one dimension of the matrix the potential candidates are lined up:</p>
<ul>
<li>Asus NAS-M25</li>
<li>Buffalo LinkStation Pro Duo</li>
<li>D-Link ShareCenter Shadow DNS-325</li>
<li>D-Link ShareCenter Pulse DNS-320</li>
<li>Fantec CL-35B2</li>
<li>Freecom Silver Store 2</li>
<li>Iomega StorCenter ix2-200</li>
<li>LG Electronics N2A2</li>
<li>Netgear ReadyNAS Duo v2 RND2000</li>
<li>Qnap Turbo NAS TS-212</li>
<li>RaidSonic Icy Box IB-NAS5520</li>
<li>Seagate BlackArmor NAS 220</li>
<li>Synology DiskStation DS212+</li>
<li>Synology DiskStation DS212j</li>
<li>Thecus N2200EVO</li>
<li>Western Digital My Book Live Duo</li>
<li>Zyxel NSA325</li>
</ul>
<p>Along the other dimension properties of interest are given. Each property gets a weighting factor that describes how important that property is in the current context (in this case my personal preference). For a NAS such properties could be noise, speed, design, price and so on. Each property must be rated in a way that makes it comparable. The rating is then multiplied by the weight for the property and the points for all properties are summed. Depending on the type of rating used, the device with the most or fewest points wins. All properties must of course be rated with the same type.</p>
<div class="wp-caption aligncenter" style="width: 510px"><img alt="" src="/media/decision-matrix-NAS.png" title="NAS decision matrix excerpt" width="500" height="300" /><p class="wp-caption-text">part of the NAS decision matrix</p></div>
<p>For the NAS decision matrix I chose a rating system where higher values equal better. I tried to keep the rating between 0 and 1 for each property in order not to fudge the weights. This is not always possible, though, and needs to be taken into account when setting the weights. For e.g. price I chose a negative value directly proportional to the cheapest price I could find (hence higher value = better), but values can be as low as −2.9 for the most expensive device in the list. With a weight of 4, that device gets nearly 12 points deducted for its high price. Other properties are easier to scale, but more difficult to quantify, such as design or software.</p>
<p>If you want to know who won, you’ll find the full matrix here:<br />
<strong><a href="https://docs.google.com/spreadsheet/ccc?key=0AhtaOwK_iVu1dFlaRFJRTEpmNW9JOE9jQWNCc1I3LVE" title="NAS decision matrix" target="_blank">NAS decision matrix (original)</a> [Google Drive]</strong></p>
<p>If you’d like to set your own weights and see what’s the best device for you, an editable version – whose content, including ratings, likely will no longer match the original – is here:<br />
<strong><a href="https://docs.google.com/spreadsheet/ccc?key=0AhtaOwK_iVu1dEN1b2VQekwyeFNNRkN0Q1laZHduUHc" title="NAS decision matrix (editable)" target="_blank">NAS decision matrix (editable)</a> [Google Drive]</strong></p>
<p>You can also download the original document and edit it locally. Just set the values in the blue fields (weights, design rating and bonus points) according to your own preferences and once you’re done, check column S to pick the winner.<br />
Some cells in the matrix are empty (white). For those I either couldn’t find that particular information or I excluded the device pretty early on and was too lazy to find out all the details. Also the references are somewhat spotty, as I started adding these quite late. Feel free to complete.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuswinter.de/archives/1647/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
