<![CDATA[Zigang Xiao]]> 2015-05-22T17:32:50-05:00 http://blog.ivansiu.com/ Octopress <![CDATA[美国留学：学生保险拔智齿]]> 2015-05-14T22:30:58-05:00 http://blog.ivansiu.com/blog/2015/05/14/study-abroad-wisdom-teeth-removal-with-student-insurance Wisdom Teeth (source)
Wisdom Teeth (source)

在快奔三的年纪，终于长出了最后一颗智齿。本来想着说这辈子不用拔智齿的——因为我25岁前就已经长完了三颗智齿，并且都 align 得非常好，并没有阻生。之前在中国时的医生也告诉我，没有必要拔掉，因为他们出来得迟，因此比起其他牙齿也会掉得迟。所以以后牙齿掉完后，他们还会在那里，可以做到固定镶牙的用途。当然我在美国没有听到有医生这样提起的，而且美国的习惯是 4 颗一起全部拔掉，一了百了！听起来有点 scary，只是他们的考虑也不是没有道理：智齿一般会长歪，即使没有长歪，也可能引发各种疾病，比如由于长得比较靠里，比较难清洁到，因此很容易蛀牙。更甚的是，蛀牙后，会引起正常的牙齿也蛀牙！这个情况就发生了在我身上：我的下面两颗支持都有蛀牙，并且引起了旁边的蛀牙！为了这个问题，我已经补过两次牙齿。这成为了我这次拔掉他们的最大原因。

我的最后一颗智齿是左上那颗，长歪了，好在不是顶着别的牙齿，而是横向的生长，朝着舌头方向长出来了。所以舌头蹭到很不舒服。大概5个多月前刚长出来时去检查过，还拍了 panarama 的 x-ray （学校的 dental delta 保险三年只 cover 一次，这次只能自费，花了大概 70 刀）。但由于只是刚长成，并不清楚趋势，因此我也带着侥幸的心理没有理他（考虑到别的三颗都乖乖的直直地长了出来！）。最近终于把找工、TA、论文的事情忙得差不多，感觉不拔不行了，赶紧联系医生。可惜之前去的 dental clinic 不能做 oral surgery，于是医生 refer 我去当地最大的 local hospital：carle。总结起来，大概 timeline 是这样的：

12月份看的牙医，拍 X-ray，医生诊断需要拔智齿，开 referal paper 让我去 carl 做『oral surgery』。我偷懒没有马上去做。

5月初打电话给 carle schedule 了一个 appointment。护士告诉我让 clinic 发 x-ray 给他们。于是我打电话让 clinic 发，他们说会在我 appointment 前发过去（结果后来没发！）

过了一个星期去做了 examination，竟然是免费的。护士帮我一检查，发觉 x-ray 竟然没发过来。于是我马上电话过去让他们发。护士和医生很好人，说如果他们不发，给我免费做一个。等了好久，终于给我发了过来。医生也是顺理成章地问了下我情况，问我要不要做 sedation，全身麻醉 (anesthesia，Dental IV)，还是做 local 的局部麻醉。作为一个小白，当然是咨询医生意见。医生说大家都做 IV，睡一觉醒来就拔好了。于是我就说好我也要（只是没想到后来麻醉竟然要 375）。由于我以为我保险马上要过期，于是眼泪汪汪地让他给我这周马上做手术。他们非常 accomodating，愣是给我 schedule 到了第二天。拔智齿在美国算是小手术了，因此要签一张 paper，类似于 disclosure。走之前，我拿着手术清单去 patient account 查价 （check against insurance），但是前台阿姨说不能马上知道结果，只能给我第二天打电话。回到家后，我对着 bill 大概估算了一下，一颗牙 285 x 4 = 1140 + 麻醉 375 = 1515，而保险的 upper limit 是 1000，即使 100% cover 也要自付 515。感觉还是太贵，于是打电话问他们能不能取消掉。得到的答复是，我必须跟医生商量。但是医生一直 busy，一直没有给我答复。直到他们下班前，护士才电话我说，第二天跟医生讲就好。整个流程持续了大概 2 个多小时，花了 3 刀 parking。

第二天早上收到医院电话，得到具体 insurance 的信息以及bill。我掐指一算：一颗牙 285 x 4 = 1140 + 麻醉 375 = 1515，但是保险 upper limit 是 1000，而且不！包！麻！醉！这样 quote 下来我的价格是 (285x4 - 45) * 30% + 375 + 45 = 748.5，其中 45 是保险的 deductible。并且由于 carle 不属于 delta dental 的 network，保险只 cover 70%，which means I pay 30%! 太贵了。于是我果断选择了只做局部麻醉，因为是免费的。这样下来就是我的 out of pocket 是 373.5, which is not too bad。果然穷人多受罪…… 不过换个角度想，全身麻醉怎么说还是比较伤身的，没用也好。不过为了预防万一，我还是做好了全身麻醉的准备。根据给我的资料，全身麻醉需要在术前8小时不能进食，任何水、candy、gum都不能吃！（据说是为了防止你大小便失禁？）由于我手术是下午1:45开始，那么算起来我最迟也要在凌晨 5 点时吃东西……要那么早爬起来准备+吃，还是算了吧。我昨天晚上是8点吃的晚饭，这样算起来我有将近 18 小时滴！水！未！进！T_T 并且由于全麻带来的作用，术后人会不清醒，还必须有人带你去医院负责把你运回家，非常严肃，当然也非常麻烦。

下午开车到了位于 champaign 的医院（carle 在 urbana 和 champaign 各有一间，医生轮岗）。check-in ，乖乖地贡献 373.5 后等了半小时进手术室。总的来说护士们都很 caring，会一直跟我聊天，也很详细地给我解释术后的一些注意事项。不久后，医生助手进来给我打麻药。老实说，整个过程中最痛的其实是这个环节，因为他们会给智齿附近的 gum 打针，扎进去恐怖+疼的感觉，一半一半吧。整个人也会不自觉地绷紧了，双手牢牢地按住自己大腿。不过其实局部麻醉对我来说也是常事了，之前补牙时也做过，所以多少有点心理准备。不久后，整个嘴麻了，连吞口水也感觉有点困难。

医生进来后手术正式开始。新出来的那颗（左上），我估计 5 秒就拔出来了，一点感觉都没有。医生会 count：this is one。我当时心里一阵窃喜，原来这么水啊！可惜如意算盘打错了，拔下面那颗时，我感觉整颗死死地嵌在牙腔里，怎么也拔不出来，牙根处有点隐隐作疼，但更疼的，是我的下巴。因为作用力太大，我感觉整个下巴都要被扯起来了…… 也许是因为太牢固，也许是因为补过牙，医生决定把它钻开再拔。于是就听到了钻头在口腔里巨大的声音。钻好后，医生估计是一片一片地拔出来的，其实我感觉不到具体手法，只知道他们一直在里面捣鼓。期间医生也会预警：你接下来会听到一些碎裂的声音…… 右上的智齿虽然也是 fully erupted，但是比起下面的好拔多了，虽然不如左上的容易，但是不需要钻就拔了出来。右下的是最 hard core 的，不仅要钻，而且钻完了也花了好大功夫才解决。估计下面的开口比较严重，所以医生都给我缝合了。没感觉到他给我穿针，但是能感觉到他拉线和打结时把牙肉缝起来。其实真正拔牙的整个流程估计不超过10分钟？老实说也没有网上写的那么恐怖，可能是我身体素质比较好吧 :)

完了后做起来歇息了一下便走了（说到这，我都佩服我自己了，没有过敏，没有烟酒，没有遗传病，没有重大病史，各种指标正常，拔牙不叫不闹，估计医生也喜欢我这种病人吧…… 感谢上天感谢爹娘给我的强壮体魄~）。回家后一直要咬着纸巾止血。大概3-4个小时候麻药效果过去了。根据护士说法，我可以服用一些 ibuprofen （美国常见止疼药）来止疼。把纸巾取出来后的大概半个小时，真的很疼。小时候牙疼的那种感觉又回来了。不过好在半小时过后就没怎么疼了，也许是止疼药功效上来了，也可能伤口愈合得好。总的来说，还是没什么大问题。

接下来要做的，就是看它恢复得如何了。刚拔完自然是不敢吃比较硬的食物的。乖乖地给自己熬了粥喝。希望身体赶紧回复过来，一周后还要去 DC 和 NY 旅行呢~


过了两周，总算没那么疼了。牙线也开始脱落，能正常吃东西了。我觉得我恢复得还是不错的，没有需要用上医生开的处方药，只是用 OTC 的 ibuprofen 即可止疼。只是每天早上起来时会比较疼，因为平躺着会让它充血。

PS. 如果有在 UIUC 的朋友也想去拔智齿，可以先去 Creative Smiles Dental （在 marketplace 那边）检查。没有租生的智齿它们是可以直接拔的。提我的名字（说我 refer 你）可以每人各拿 $50 的优惠 :)

<![CDATA[Popular watches under $150]]> 2015-05-04T13:24:35-05:00 http://blog.ivansiu.com/blog/2015/05/04/popular-watches-under-150

I’ve been looking around entry-level watches for some time. Recently, I answered a question in Zhihu (Chinese Quora), and I feel like to transcribe this collection in my blog.

Dress Watch

Rodina R005, $119 via Amazon
Rodina R005, $119 via Amazon

This watch is discussed in my previous blog post. It is a bit debatable as some people think it completely ripoff the NOMOS Tangente. However, considering there so many Rolex Submariner homages, this should also considered a homage. It uses a Seagull ST1701 movement, sapphire crystal, and display case back. At this price point, it is really a good deal. Get in on Amazon.

Orient Bambino, $130 via Amazon
Orient Bambino, $130 via Amazon

I’ve always like the ORIENT logo, much more than SEIKO’s. This watch features Roman literals, blue hands and white classic dial. Amazon

Daniel Wellington, $120 Men $85 Women

This has been quite popular in China, due to their successful marketing campaign. It is a quartz (Japanese) watch with multiple variation, and looks really good. Get the best looking ones here and here.

Diver’s Watch

Now moves to my favorite category. Rolex designed the true classic look of today’s diver’s watch. However, the retail price for a submariner is probably too high for lots of people. Fortunately, Japanese brands SEIKO and ORIENT provide some affordable options here.

SEIKO skx007
SEIKO skx007

A very popular one. Considered as a poor man’s Rolex. You can get it around $180 at Amazon.

Orient Ray
Orient Ray

Also a very popular one. As I said, I really like Orient’s LOGO. I find it far more interesting to see the lions and shields rather than just the word “SEIKO”. $130 at Amazon.

Orient Mako
Orient Mako

Ray’s brother, Mako. The watch face is slightly different, thinner hands, arabic numbers at 6, 9 and 12 o’clock. Also around $130 at Amazon.

Field/Flight/Pilot Watch

Seiko SNZG13

One of my favorite. It’s lume is fantastic and got countless compliments. Only $100 at Amazon.

Orient FER2A001B0 Pilot Watch

This is my favorite style. Look at the beautifully designed digits! It’s lume is also awesome: lumes at all numbers! When it’s on sale you can get it at $125.


Bestseller in Amazon. Come with various colors (black, green, blue, beige). It’s so cheap ($50) that people are getting all colors and rotate everyday. Also, since it’s so affordable, it will become your workhorse. You won’t treat it like million dollar watch that only put in your locker.

Skeleton Watch

Seagull M182SK
Seagull M182SK

Quite popular in watchuseek forum. Very nice seagull movement with a complete see-through design. That said, it might be too busy to see the hands. $135 at Amazon.

Fossil Grant
Fossil Grant

This skeleton is cleaner than the Seagull’s. Nevertheless, Seagull is more reputable than Fossil in watch making. Amazon.


So there you have it. These watches are very affordable and have the great quality that earn them reputation. You can see them in nearly every watch forums. If you just started watch collecting, consider getting one of them. Let me know if you have any other suggestions.

<![CDATA[Watch Review: Rodina R005GB]]> 2015-03-26T23:04:16-05:00 http://blog.ivansiu.com/blog/2015/03/26/watch-review-rodina-r005gb Tangente



The Review





This is really how it should come:









  • Affordable price
  • Good style, similar to the famous NOMOS Bauhaus style
  • Seagull ST1713 automatic movement
  • 5ATM (instead of 3ATM)
  • Stainless steel case
  • Sapphire crystal!


  • Noisy winding action
  • Fonts in the dial do not match
  • Blue coating in the crown not printed at the perfect location
  • Whether it is a copycat or homage is debatable.



<![CDATA[精英主义与投票考试]]> 2014-10-01T22:29:30-05:00 http://blog.ivansiu.com/blog/2014/10/01/jing-ying-zhu-yi-yu-tou-piao-kao-shi 题记

有感于最近香港要求普选的民运，心中大概有点想法。考虑到自己对政治的认识与时间的限制，为了防止与 别人无谓的争辩， 不想把这些想法发到社交网络上，毕竟，这只是个人的想法，或者更严格来说， 是一种理念。因为很多主义与思想，都没有绝对的对错，我们只能做到根据自己的人生观与思想来 做出取舍。而偏偏这个世界上又很多人喜欢跟别人 argue，一定要说服别人为止——我根本没有这个时间 与精力去辩论。另外，这也同时印证了我为什么是 pro-精英主义的，我深知自己对这些事物的认识 不够，所以自觉需要更严谨的学习才有资本与别人争论。我相信多年以后，自己的看法一定又会 有所改变。彼时回首看这些文章，一定会觉得自己幼稚。不过无论怎么说，还是记录下自己的想法。


我对这件事情的看法很复杂——我对于民运人士的诉求部分支持又带有保留。争取投票权与心中的理想 当然是一种很好的东西，这点我是支持的。但是普选是否就意味着民主？更大的两个问题是，

  1. 普选就能保证选出来的人代表民意吗？ 这就相当于是多数人的暴政。对于这点，已经有很多论述。 这不是我的主要主题，在此不述。

  2. 如何保证选民投票的质量？ 很显然很多人限于知识水平，也许只能看到对自己最直接的利弊影响， 而并无法理解哪位候选人的纲领政策对社会，对国家，对世界的更深层次影响，反过来说，这些影响 也许反而会给自己带来并不那么直接的有害效益。 同时，没有自己独立思考过的选民，往往对候选人的印象仅仅来源于道听途说以及政治宣传，甚至 金钱操作，因此这些投票是受到影响的。而『知道自己在做什么』的人实在太少了，这一点在我 求学生涯中越来越明显越来越深刻。我见过太多例子，并不是表面直觉看起来那么简单，经过 深层分析抽丝剥茧后，才发觉真相往往是非常 counter-intuitive 的。对于知识水平完全不在 一个层面的人的 bold move，很多时候只能说 『too simple, sometimes naive』。


第二点体现了我 pro-精英主义的最重要原因。想对地，支持普选的更偏向于民粹主义。 两者都有他们的 pros and cons。这两篇文章介绍得很详细：


就投票权这一点来说，这两种主义就相当于两个极端：一个是认为选票控制在精英手里，一个是认为 人人有选票。我希望选票最终是要受到限制的，但是这个限制在公平与效益最大化的前提下做到最小。

一个可能的解决方案，就是进行 voter’s test。就好像高考一样，诚然每个人都应该享有教育权， 但是在现实资源的限制下，我们必须用考试这种相对公平的方法来保证我们的资源要用在对的人 身上，对于参考者来说，也算是进行了投入，付出了机会成本，并且能认识到这个权利是要争取回来的。 同时，这个考试，也保证了投票者具有基本的知识修养。另外打一个比方，就是人人都可以享有路权（投票权）， 但是要真正在马路上开车行驶（行使投票权），就必须对他人负责，通过考试来证明自己有资格使用这条路 并且不会影响他人的生命安全（投票时做出理性选择）。这里有篇文章与我观点类似。

这不是一个新的 idea，事实上，美国以前为了限制黑人投票，的确也实行过类似的考试。但那并不是说 这个制度就行不通，只是当时它被 abuse 了。这个考试必须是公平的，比如我们不设任何年龄与学历限制。这篇文章介绍了一些背景，里面提到了一些支持 voter’s test 的。当然，我再次认识到这只是自己的主观认识，而且没有经过大量的背景阅读，所以很可能 这个制度会有更深层的问题。日后我会继续就这个 topic 展开讨论。

<![CDATA[Notes on Maximum Likelihood, Maximum A Posteriori and Naive Bayes]]> 2014-09-24T15:41:44-05:00 http://blog.ivansiu.com/blog/2014/09/24/notes-on-maximum-likelihood Let \(\data\) be a set of data generated from some distribution parameterized by \(\theta\). We want to estimate the unknown parameter \(\theta\). What we can do?

Essentially, we want to find a most likely value of \(\theta\) given \(\data\), that is \(\arg \max P(\theta | \data)\). According to Bayes Rule, we have

\[ P(\theta \given \data) = \frac{P(\data \given \theta)P(\theta)}{P(\data)} \]

and the terms have the following meanings:

  • \(P(\theta \given \data)\): Posterior
  • \(P(\data \given \theta)\): Likelihood
  • \(P(\theta)\): Prior
  • \(P(\data)\): Evidence

Maximum Likelihood Estimation (MLE)

An easy way out is to use the MLE method. We want to find a \(\theta\) the best explains the data. That is, we maximize \(P(\data \given \theta)\). Denote such a value as \(\hat{\theta}_{ML}\). We have

\[ \hat{\theta}_{ML} = \argmax_\theta P(\data \given \theta) = \argmax_\theta P(\mathbf{x}_1, \ldots, \mathbf{x}_N \given \theta ) \]

Note that the above \(P\) is a joint distribution over the data. We usually assume the observations are independent. Thus, we have

\[ P(\mathbf{x}_1, \ldots, \mathbf{x}_N \given \theta ) = \prod_{i=1}^{N} P(\mathbf{x}_i \given \theta ) \]

We usually use logarithm to simplify the computation, as logarithm is monotonically increasing. Thus, we write:

\[ \mathcal{L}(\data \given \theta) = \sum_{i=1}^N \log P(\mathbf{x}_i \given \theta ) \]

Finally, we seek for the ML solution:

\[ \hat{\theta}_{ML} = \argmax_\theta \mathcal{L}(\data \given \theta) \]

If we know the distribution \(P\), we can usually solve the above by setting derivative of \(\theta\) to 0 and solve for \(\theta\), that is,

\[ \frac{\partial L}{\partial \theta} = 0 \]

Maximum A Posteriori (MAP)

In MAP, we maximize \(P(\theta \given \data)\) directly. Denote the MAP hypothesis as \(\hat{\theta}_{MAP}\), we have:

\[\begin{array}{rl} \hat{\theta}_{MAP} = & \argmax_\theta P(\theta \given \data) \\ = & \argmax_\theta \frac{P(\data \given \theta)P(\theta)}{P(\data)} \\ = & \argmax_\theta P(\data \given \theta)P(\theta) \end{array}\]

Note that the last step is due to the evidence (data) \(\data\) is constant, and thus can be omitted in \(\argmax\).

At this step, we notice that the only difference between \(\hat{\theta}_{ML}\) and \(\hat{\theta}_{MAP}\) is the prior term \(P(\theta)\). Another way to interpret is that we consider \(MAP\) is more general than \(MLE\), as if we assume all the possible \(\theta\) are equally probable a priori, e.g., they have the same prior probability, or uniform prior, we can effectively remove \(P(\theta)\) from the MAP formula, and it looks like exactly the same as MLE.

Finally, if the independent observation holds, again we can use logarithm and expand \(\hat{\theta}_{MAP}\) as:

\[ \begin{array}{rl} \hat{\theta}_{MAP} = & \argmax_\theta L(\data \given \theta) \\ = & \argmax_\theta \sum_{i=1}^{N} \log P(\mathbf{x}_i \given \theta ) + \log P(\theta) \end{array} \]

The extra prior term has the effect that we are essentially ‘pulling’ the \(\theta\) distribution towards prior value. This makes sense as we are putting our domain knowledge as prior and intuitively the estimation is biased towards the prior value.

Naive Bayes Classifier

Assume that we are given a set of data \(\data\), where each example \(\mathbf{x_j}=(a_1, a_2, \ldots, a_n)\), which can be viewed as conjunctions of attributes values. \(v_j \in V\) is the corresponding class value. Using MAP, we can classify an example \(\mathbf{x}\) as:

\[v_{MAP}=\argmax_{v_j\in V} P(v_j \given a_1, \ldots, a_n)\]

The problem is that it is hard to find a joint distribution for \(P(\mathbf{x} \given \theta)\). If we use the data to estimate the distribution, we typically don’t have enough data for each attribute. In other words, the data we have is very sparse compared to the whole distribution space.

Naive bayes makes the assumption that each attribute is conditionally independent given the target class \(v_j\), that is,

\[P(a_1, \ldots, a_n \given v_j) = \prod_{i=1}^n P(a_i \given v_j)\]

which can be easily estimated from the data. Thus, we have the following naive bayes classifier:

\[v_{NB} = \argmax_{v_j \in V} P(v_j) \prod_{i=1}^n P(a_i \given v_j)\]

Note that the learning of naive bayes simply involves in estimating \(P(a_i \given v_j)\) and \(P(v_j)\) based on the frequencies in the training data.

Normally the conditional independence assumption does not hold, but naive bayes performs well even if so. More importantly, when conditional independence is satisfied, Naive Bayes corresponds to MAP classification.


MLE, MAP and Naive Bayes are all connected. While MLE and MAP are parameter estimation methods that returns a single value of the paramter being estimated, NB is a classifier that predicts the probability of the class that an example belongs to. We also have the following insightes:

  • Given the data, MLE considers the paramter to be a constant and estimates a value that provide maximum support for the data.
  • MLE does not allow us to ‘inject’ our beliefs about the likely values for the parameter (prior) in the estimation process.
  • MAP allows the fact that the paramter can take values from a prior (non-uniform) distribution that express our prior beliefs regarding the paramters.
  • MAP returns paramter value where the probability is highest given data.
  • Again, both MLE and MAP returns a single and specific value for the paramter. By contrast, bayesian estimation computes the full posterior distribution \(P(\theta \given \data)\).


After reading this article, I have the following interpretation:

  • The Maximum Likelihood approach can be roughly regarded as traditional “frequentist” thinking.
  • The MAP approach is a direct applicatin of Bayes Theorem. Thus, it can be regarded as a “bayesian” way of thinking.
<![CDATA[Fix Mid 2009 MBP RAM not recognized issue]]> 2014-05-28T23:30:56-05:00 http://blog.ivansiu.com/blog/2014/05/28/fix-mid-2009-mbp-ram-not-recognized-issue Possible cause of unrecoganized RAM
Possible cause of unrecoganized RAM

A few days ago, I encountered an issue which seems to be common among mid-2009 MBPs: one of the RAM (in slot 1) is not recognized anymore. Or, sometimes it is recognized, but after sleep and wake up, the computer freezes and impossible to recover but force power off.

It turns out this is a common issue in this model. See the discussion in this thread and this thread. In the following, I am going to present my temporary fix for this problem. For those of you that still want to stick to the old MBP, the fix shall last for a while. But I do recomend you backup all the files and prepare to migrate some day soon.

As I suggested in my reply, this may due to a RAM slot degradation. My guess is, the RAM slot cannot align the RAM to a correct contact positions any more. Precisely, see the post image above. Notice that the two clips on the left and right are used to hold the rams in a horizontal position, otherwise they will bend upwards. I took a close look at those clips and found that the plastic wore out and cannot hold them as original. I don’t have great ways to fix them, so I just cropped some papers and insert them between the RAMs and the back edges on the body, hoping they can help tucking the RAMs.

As I am fixing it, I accidentally broke the left holder. So I have to customized a plastic holder and stuck it with the logic board to hold the inner ram (slot 1).

To verify my theory, I then taped a padding at the corresponding RAM position in the back cover:

And they look like the following before I close:

Note that you have to screw it real tight to create the pressure such that the RAM is aligned. That said, there will be a ‘bump’ at that position, and will easily cause scratch. So I use an apple sticker to cover my ass:

This method worked for me, well, at 99% of the time. Sometimes after sleep, the MBP still won’t wake up. I notice that this usually due to running the MBP for a long time, and it’s hot inside. Nevertheless, this is the best solution I can come up with by now. If you have any other cheap solution that does not require replacing the logic board, please let me know in the comments.

Finally, Zach Clawson created a dedicated page for this issue, which lists lots of reference and provides explanation to it. Make sure you check it out if you have encountered similar issue.

There are other common issues for this model, and they can be easily fixed. See my following posts:

If you have similar experience, do not hesitate to let me know. If you find my instruction helpful, leave a comment and share it!

<![CDATA[Replacing SATA cable in Mid 2009 MBP]]> 2014-05-28T02:15:08-05:00 http://blog.ivansiu.com/blog/2014/05/28/replacing-sata-cable-in-mid-2009-mbp Replacing MBP cable
Replacing MBP cable

Recently, my mid 2009 MBP (Model A1278) fails to recognize the hard drive. My first bet was another disk failure on me, but it was not the case. I took down the hard drive and put it to a mobile hard drive case and it can be read smoothly.

It turns out that it is due to the SATA cable fault, which is a notorious problem for mid 2009 MBP model. See the threads and discussions here, here, here and here.

Luckily, the solution is simple, just go ahead and purchase a replacement cable and replace it. iFixit has a very detailed illustrated document on the procedures. However, Amazon has a cheaper option, and it works fine for me. I didn’t test the infra-red though, since I never and not plan to use it.



<![CDATA[My Octopress Blogging Flow]]> 2014-05-22T22:38:07-05:00 http://blog.ivansiu.com/blog/2014/05/22/my-octopress-blogging-flow Writing in Sublime Text and previewing in Marked
Writing in Sublime Text and previewing in Marked

After blogging with Octopress for a while, I have already gained some insights on it, and my publishing flow has been smoother. I think it is right time to share my flow as a reference.

The Flow

The following sections outlines the flow. The last section contains assorted tips and tricks. For the basic configuration of Octopress, please refer to the official website. I also recommend installing Alfred.app.

Creating a post: alfred workflow (blog publish)

Artem Yakimenko created an awesome alfred workflow for publishing and generating octopress websites. Use blog publish [title] to create a new post:

It then opens the post in your specified text editor with template.

Editing: Sublime Text.app + Marked.app + Marked App Menu (ST Plugin)

I use Sublime Text (ST) as my text editor, because it provides VIM keybinding and there is a huge repository of plugins. While editing, I use [Marked] to instantly render the markdown file and view the result. In fact, the title image shows my editing and previewing in action.

To make the process sweeter, there is a ST plugin called Marked App Menu that allows you to open the current file in Marked. Just search in ST Package Control to install it.

Previewing: pow + rake watch + pow alfred workflow

To preview the generate website, simply install pow and execute rake watch under octopress directory to monitor the change. Octopress official website provides some explanation. After installation, you can view your website locally at http://octopress.dev.

You should also install the pow alfred workflow, which can help you open pow website in a breeze.

Math Rendering: MathJax

Since I am an EECS student, I write a lot of Optimization, Machine Learning and Computer Vision stuff, which relies heavily on mathematics. Thus, writing math formulas is a must for me. MathJax is a javascript library for rendering math by writing LaTeX math. To do this, one needs to configure the site and link to the library. Put these two lines into <octopress>/source/_includes/custom/head.html:

<script type="text/javascript"

<script type="text/javascript" src="/javascripts/MathJaxLocal.js"></script>

The first script block loads MathJax, and the second loads a custom configuration in source/javascripts/MathJaxLocal.js. It is a good place to write your own macro there. For instance:

  TeX: {
      equationNumbers: { autoNumber: "AMS" },
      TagSide: "left",
      Macros: {
          reals: ['\\mathbb{R}'],
          complex: ['\\mathbb{C}'],
          norm: ['\\left\\lVert#1\\right\\rVert', 1],
          given: ['\\:#1\\vert\\:', 1],
          data: ['\\mathcal{D}'],


Now you can write math!


There are a couple of good articles for reference:

  1. Blogging With Math: Octopress, MathJax, and Pandoc
  2. Writing Math Equations on Octopress
  3. LaTeX Math in Octopress

Image hosting: Dropbox public folder

I host my images in Dropbox Public folder, since you can simply copy the public link and paste it to the post source, for example:

Image editing: Skitch + OmniGraffle

The previous image is done by a timed capture from skitch. For advanced vector graphics, I use OmniGraffle.

Markdown converter: pandoc

Pandoc is a swiss-army knife like tool that convert documents in multiple formats to several dozens of output formats. I mainly use it as the markdown converter for Octopress. A plugin can help you with that.

After installation, I update the markdown section of _config.yml with the following:

markdown: pandoc
  format: html5
    - smart
    - mathjax
    - bibliography: source/blog.bib
    - csl: _style/ieee.csl

which tells Octopress to use pandoc, and pass the option smart, mathjax and use the style file ieee.csl to format the biliography blog.bib. For example, refer to [@xiao2013optimally] generates refer to [1] (scroll down to see the References section).

Pandoc’s Markdown Reference: Dash.app and Dash alfred workflow

Dash.app is an API Documentation Browser and Code Snippet Manager. It provides an convinient alfred workflow that searches the documents:


Tips and tricks

Continuously growing…

  • There are lots of undocumented/less documented things in Octopress, which can help you write blog posts kinda ‘programmatically’. For example, http://blog.ivansiu.com returns the url of site, which is http://blog.ivansiu.com in my case. In fact, anything in _config.yml is a variable under site.


In conclusion, Octopress is a revolutionary blogging framework. It provides a robust static site building framework (jekyll, bootstrap, scss, etc.) and allows complete control over the source, which is perfect for users that have basic coding and source control skills. In fact, it gives me a similar feeling of getting touch with a Mac. That is, compared to Windows, which is too close and does not provide built-in programming-friendly environment (Console, UNIX stuff, etc.), and compared to Linux, which is very open but too many variations and too many customizations needed, it combines their advantages by presenting a user- friendly interface and provides all sorts of underlying UNIX tools. I am very satisfied about this and my intention to write posts have revived. However, some sort of basic configuration is still needed. In particular, I would say Mathjax rendering and better image support definitely need to be integrated in the next release.

What’s your thought? Do you have any neat tricks publishing with Octopress? Please leave your comments.


[1] Z. Xiao, Y. Du, H. Tian, and M. D. Wong, “Optimally minimizing overlay violation in self-aligned double patterning decomposition for row-based standard cell layout in polynomial time,” in Computer-aided design (iCCAD), 2013 iEEE/aCM international conference on, 2013, pp. 32–39.

<![CDATA[Sparse Image Reconstruction via L1-minimization]]> 2014-05-19T15:12:36-05:00 http://blog.ivansiu.com/blog/2014/05/19/sparse-image-reconstruction-via-l1-minimization phantom_orig phantom_backproj phantom_tv Original Minimum Energy Reconstruction Sparse Reconstruction


This is a follow up of the L1-minimization series. The previous two posts are:

  1. A Comparison of Least Square, L2-regularization and L1-regularization
  2. Sparse Signal Reconstruction via L1-minimization

We have explored using L1-minimization technique to recover a sparse signal. The example shows a 1D example. This post demonsrates on a 2D example, where the image is viewed as a signal. This makes sense as we can perform 2D Fourier Transform in the image, where the basis are a combination of horizontal and vertical waves. For a complete introduction to FFT on images, refer to this tutorial. Notice that similar to 1D signal, we do not measure the image directly in time domain, but we do it in the frequency domain. Concretely, say \(x\) is the 2D image collapsed to 1D, and \(A \in \reals^{k\times n}\) is the measurement matrix, \(b\) is the observation, we then have \(Ax=b\). Usually we will require \(k = n\) to obtain an exact solution for \(x\) given \(A\) and \(b\). Now, if we use FFT and obtain the frequency coefficients as \(\hat{x}\), we can also perform similar measurements \(\hat{A} \hat{x} = \hat{b}\), and the requirement \(k = n\) is the same. In other words, the required samples (the information) is the same. By using the inverse fourier transform, we can convert \(\hat{x}\) back to \(x\). The only difference is that the measurement \(\hat{A}\) is taken in frequency (Fourier) domain. As we can see later, we can utilize sparse information to reduce \(k\).

Image Gradients and Total Variation

We first introduct the concept of image gradients. For any 2D real image I, if we think about each row as a signal, we can then view the ‘difference’ between adjacent pixels as (horizontal) gradient Gx(I), this makes sense since a sharpe change denotes an edge. Similary, we can define the vertical gradient Gy(I) for columns. Thus, we have

\[Gx(I) = \begin{cases} I_{i+1, j} - I_{ij} & i < n \\ 0 & i = n \end{cases} \qquad Gy(I) = \begin{cases} I_{i, j+1} - I_{ij} & j < n \\ 0 & j = n \end{cases}\]

where the image size is \(n\times n\).

Collectively, the image gradient G(I) is defined as the magnitude (2-norm) of both components:

\[G(I)_{ij} = \sqrt{(Gx(I)_{ij})^2 + (Gy(I)_{ij})^2}\]

The following shows Gx, Gy and G of the phantom image:

phantom_gx phantom_gy phantom_gI
Gx(I) Gy(I) G(I)

The total variation TV(I) of an image is just the sum of this discrete gradient at every point.

\[TV(I)= \norm{G(I)}_1 = \sum_{i,j} G(I)_{ij}\]

We notice that \(TV(I)\) is just the L1-norm of \(G(I)\), which leads us to the following: if we have an image that is sparse in its image gradients, we can exploit that and use our L1-minimization trick.

Sparse Gradient Image Reconstruction

The ratio of non-zero elements in Gx, Gy and G of the phantom image is 0.0711, 0.0634 and 0.0769, respectively. These ratios are really small - and we consider the gradient as sparse.

Let \(F: \reals^{n\times n} \to \complex^{n\times n}\) be the FFT operator, and \(F I\) be the Fourier transform taken on image I. Define a set \(\Omega\) as the \(k\) two-dimensional frequencies chosen according to some sampling pattern from the \(n \times n\). We further define \(F_\Omega I: \reals^{n \times n} \to \complex^k\) as the \(k\) observation taken from the fourier transform of image I. We can then solve the following optimization problem to recover \(I\):

\[\min_I \norm{F_\Omega I - b}^2_2\]

where \(F_\Omega\) can be view as the measurement matrix, \(b\) is the observation, and we want to find \(I\) such that the reconstruction cost (energy) is minimized.

However, the above does not quite work. As we can see in the following images, the L2-minimization does a poor job, either for a random measurement or a radial measurement [4] in Fourier domain.

M rand phantom rand bp phantom rand tv
Random measurement L2-minimization L1-minimization
M radial phantom_backproj phantom_tv
Radial measurement L2-minimization L1-minimization

To utilize the sparse information, we add a L1-regularization term to the above objective function, which yields the following:

\[(TV_1) \quad \min_I \norm{F_\Omega I - b}^2_2 + \lambda TV(I)\]

Without surprise, optimizing the above gives us a perfect reconstruction of the original image. It is shown that if there exists a piecewise constant I with sufficiently few edges (i.e., \(G(I)_{ij}\) is nonzero for only a small number of indices i, j), then \((TV_1)\) will recover I exactly.

A heavily commented code example is available in my github repository. Leave a comment if you have any question.

Probing Further

Now, take a look at another example cameraman, which has the following gradients (intensity rescaled using matlab’s imagesc.

cameraman cameraman_grad
Cameraman Gradient

The following shows the reconstructions (left two are using random measurements, right two are using radial measurements).

cameraman_rand_bp cameraman_rand_tv cameraman_bp cameraman_tv
Rand (L2) Rand (L1) Radial (L2) Radial (L1)

As we can see, the results are not as good. In fact, the non-zero ratio of its gradient is 0.9928, which is not sparse at all. However, if we plot the histogram of gradients, we will find that most of the gradient magnitudes are small:

Gradient Histogram
Gradient Histogram

In particular, most of them are smaller than 200, which means the number of ‘changes’ that are larger than 200 is small. In fact, the ratio of gradient > 200 is only 0.0964! Thus, there are two possible ways to discard these information and get a ‘compressed’ image that is sparse in gradients:

  1. Use mean-shift algorithm to segment the regions such that they have the same color intensities. K-means or quantization should achieve a similar result, though might not as good as mean-shift.
  2. Use image filtering to smooth the image, which can effectively average colors and discard high frequency information.

I’ll leave these conjectures for furture implementation. For those intereted, please try them yourself and let me know your results. If you have any thoughts, do not hesitate to leave a comment.


For interested readers, the following references will be helpful.

[1] E. Candes and J. Romberg, “l1-magic: Recovery of sparse signals via convex programming,” vol. 4, 2005.

[2] J. S. Hesthaven, K. Chowdhary, E. Walsh, and others, “Sparse gradient image reconstruction from incomplete fourier measurements and prior edge information,” IEEE TRANSACTIONS ON IMAGE PROCESSING, 2012.

[3] J. K. Pant, W.-S. Lu, and A. Antoniou, “A new algorithm for compressive sensing based on total-variation norm,” in Circuits and systems (iSCAS), 2013 iEEE international symposium on, 2013, pp. 1352–1355.

[4] E. J. Candès, J. Romberg, and T. Tao, “Robust uncertainty principles: Exact signal reconstruction from highly incomplete frequency information,” Information Theory, IEEE Transactions on, vol. 52, no. 2, pp. 489–509, 2006.

<![CDATA[Sparse Signal Reconstruction via L1-minimization]]> 2014-05-18T22:13:08-05:00 http://blog.ivansiu.com/blog/2014/05/18/sparse-signal-reconstruction-via-l1-minimization Sparse Signal Reconstruction Results

This is a follow-up of the previous post on applications of L1 minimization.

As we know, any signal can be decomposed into a linear combination of basis, and the most famous one is Fourier Transform. For simplicity, let’s assume that we have a signal that is a superposition of some sinusoids. For example, the following:


With discrete consine transform (DCT), we can easily find the coefficients of corresponding sinusoid components. The above example’s coefficients (in frequency domain) and signal in time domain are shown in the post figure.

Now, let’s assume we do not know the signal and want to reconstruct it by sampling. Theorectically, the number of samples required is at least two times the signal frequency, according to the famous Nyquist–Shannon sampling theorem.

However, this assume zero-knowledge about the signal. If we know some structure of the signal, e.g., the DCT coefficients are sparse in our case, we can further reduce the number of samples required.1

The following code snippet demonstrates how this works. We generate the original signal in time domain and then perform a DCT to obtain the coefficients.

% sparse signal recovery using L1

N = 256; R = 3; C = 2;

% some superposition of sinoisoids, feel free to change and experiment
f = @(x) .5*sin(3*x).*cos(.1*x)+sin(1.3*x).*sin(x)-.7*sin(.5*x).*cos(2.3*x).*cos(x);
x = linspace(-10*pi, 10*pi, N);
y = f(x);

coef = dct(y)';
xlim([0 N]); title('Original signal in frequency domain');

xlim([min(x) max(x)]); title('Original signal in time domain');

Let’s assume that we have a device that can sample from the frequency domain. To do this, we create a random measurement matrix to obtain the samples. We use 80 samples here. Note that we normalize the measurement matrix to have orthonormal basis, i.e., the norm of each row is 1, and the dot product of different row is 0.

% measurement matrix
A=randn(K, N);

% observations

We first try a least-square approach, which boils down to inverse the matrix and obtain \(\hat{x}=A^{-1} b\). Note that as A is not square, we are using its pseudo-inverse here. Furthermore, as A is othornormal, its transpose is the same as pseudo-inverse.

% min-energy observations
c0 = A'*b; % A' = pinv(A) here since A is a full-rank orthonormal matrix
xlim([0 N]); title('Minimum energy recovery - coef');

y0 = idct(c0, N);
plot(1:N, y0,'r', 1:N, y, 'b');
xlim([0 N]); title('Minimum energy recovery - signal');
legend('Recovered', 'Original');

As we can see, there are lots of non-zeros in the coefficients, and the recovered signal is very different from the original signal.

Finally, we use L1-minimization for reconstruction. I used lasso to perform a L1-regualarized minimization. Another package that performs various L1-minimization is l1-magic.

% L1-minimization
[c1, fitinfo] = lasso(A, b, 'Lambda', 0.01);
% If use L1-magic
% addpath /path/to/l1magic/Optimization
% [c1] = l1eq_pd(c0, A, [], b, 1e-4);
xlim([0 N]); title('L1 recovery - coef');

y1 = idct(c1, N);
plot(1:N, y1, 'r', 1:N, y, 'b');
xlim([0 N]); title('L1 recovery - signal');
legend('Recovered', 'Original');

The above shows that L1-minimization successfully recovered the original signal. A complete code snippet can be found here.

  1. In order to recover f perfectly, we need at least \(B \log (N)\) samples (source).

<![CDATA[A Comparison of Least Square, L2-regularization and L1-regularization]]> 2014-05-14T21:32:38-05:00 http://blog.ivansiu.com/blog/2014/05/14/a-comparison-of-least-square-l2-regularization-and-l1-regularization Recovered Coefficients by Different Methods
Recovered Coefficients by Different Methods

Problem Setting

Ordinary Least Square (OLS), L2-regularization and L1-regularization are all techniques of finding solutions in a linear system. However, they serve for different purposes. Recently, L1-regularization gains much attention due to its ability in finding sparse solutions. This post demonstrates this by comparing OLS, L2 and L1 regularization.

Consider the following linear system:

\[Ax = y\]

where \(A \in \reals^{m \times n}\), \(m\) is the number of rows (observations) and \(n\) is the number of columns (variable dimension), \(x\) is the variable coefficients and \(y\) is the response. There are three cases to consider:

  1. \(m=n\). This is the common-seen case. If \(A\) is not degenerate, the solution is unique.
  2. \(m>n\). This is called over-determined linear system. There is usually no solutions, but an approximation can be easily found by minimizing the residue cost \(\norm{Ax-y}^2_2\) using least square methods, and it has a nice closed-form solution \(x_{ls}=(A^T A)^{-1} A^T y\). In L2-regularization, we add a penalize term to minimize the 2-norm of the coefficients. Thus, the objective becomes: \[\min_x \norm{Ax-y}^2_2 + \alpha \norm{x}_2\] where \(\alpha\) is a weight to decide the importance of the regularization.
  3. \(m<n\). This is called under-determined linear system. There is usually no solution or infinite solutions. This is where it get interesting: when we have some prior knowledge in the solution structure, such as sparsity, we can have a ‘metric’ to find a better solution among a whole bunch. The objective is thus: \[\min_x \norm{Ax-y}^2_2 + \alpha \norm{x}_1\] The optimization technique for the above problem is called lasso, and there is an advanced version called elastic net, which combines the L2 and L1 regularization together, hoping to get the advantages of both: L1 regularization finds sparse solution but introduces a large Mean Square Error (MSE) error, while L2 is better at minimizing MSE.

An Example

In the following, we show their performances by solving a simple case.

% Compare Ordinary Least square (no regularization), L2-reguarlized (Ridge),
% L1-regualarized (Lasso) regression in finding the sparse coefficient
% in a underdetermined linear system

rng(0);  % for reproducibility
m = 50;  % num samples
n = 200; % num variables, note that n > m

A = rand(m, n);
x = zeros(n, 1);
nz = 10; % 10 non-zeros variables (sparse)
nz_idx = randperm(n);
x(nz_idx(1:nz)) = 3 * rand(nz, 1);
y = A*x;
y = y + 0.05 * rand(m, 1); % add some noise

% plot original x
subplot(2, 2, 1);
bar(x), axis tight;
title('Original coefficients');

x_ols = A \ y;
subplot(2, 2, 2);
bar(x_ols), axis tight;
title('Ordinary Least Square');
y_ols = A * x_ols;

% L2 (Ridge) 
x_l2 = ridge(y, A, 1e-5, 0);  % last parameter = 00 to generate intercept term
b_l2 = x_l2(1);
x_l2 = x_l2(2:end);
subplot(2, 2, 3);
bar(x_l2), axis tight;
title('L2 Regularization');
y_l2 = A * x_l2 + b_l2;

% L1 (Lasso)
[x_l1, fitinfo] = lasso(A, y, 'Lambda', 0.1);
b_l1 = fitinfo.Intercept(1);
y_l1 = A * x_l1 + b_l1;
subplot(2, 2, 4);
bar(x_l1), axis tight;
title('L1 Regularization');

% L1 (Elastic Net)
[x_en, fitinfo_en] = lasso(A, y, 'Lambda', 0.1, 'Alpha', 0.7);
b_en = fitinfo_en.Intercept(1);
y_en = A * x_en + b_en;

MSE_y = [mse(y_ols-y), mse(y_l2-y), mse(y_l1-y), mse(y_en-y)];
disp('Mean square error: ')
fprintf('%g    ', MSE_y); fprintf('\n\n');

% Plot the recovered coefficients
figure, hold on
plot(x_l1, 'b');
plot(x_en, 'r');
plot(x, 'g--');
legend('Lasso Coef', 'Elastic Net coef', 'Original Coef');


Mean square error:
1.81793e-29    7.93494e-15    0.0975002    0.0641214

The above code snippets generates an under-determined matrix \(A\), and a sparse coefficients which has 200 variables but only 10 of them are non-zeros. Noises are added to the responses. We then run the proposed three methods to try to recover the coefficients. It then generates two plots:

  1. The first plot is as shown in the top. As we can see, OLS does a very bad job, though the MSE is minimized to zero. L2-regularization do find some of the sparks, but there are also lots of non-zeros introduced. Finally, L1-regularization finds most of the non-zeros correctly and resembles the original coefficients most.
  2. The second plot shows how similar the recovered coefficients by lasso and elastic nets resemble the original coefficients. As we can see, both of them can recover most parts, while elastic nets contain some small ‘noise’. However, elastic net yields a slightly better MSE than lasso.
Plot of Coefficients
Plot of Coefficients

Probing Further

Scikit has some excellent examples on regualarization (1, 2). Quora has an excellent discussion on L2 vs L1 regualarization. I found the top three answers very useful in understanding deeper, especially from the Bayesian regularization paradigm perspective by thinking the regularization as MAP (Maximum A Posteriori) that adds a Laplacian (L1) or Gaussian (L2) prior to the original objective.

<![CDATA[Debugging AppleScript: print to a file]]> 2014-05-02T16:26:50-05:00 http://blog.ivansiu.com/blog/2014/05/02/debugging-applescript-print-to-a-file Debugging AppleScript is easy when you work with the script editor, simply use log to print out anything in the console. However, after you compiled it to an app, this cannot work anymore.

I find there are several ways to do it in this thread. The two approaches that work best for me are:

  1. Use logger to log to the syslog. E.g.,
do shell script "logger -t 'AS DEBUG' " & myObj

However, I don’t know why sometimes this is not logged. So I will use the following:

  1. Echo to file
do shell script "echo " & quoted form of (myObj as string) & ¬
    " >> ~/Desktop/as_debug.txt"
<![CDATA[OS X: reveal file in console]]> 2014-05-01T19:58:20-05:00 http://blog.ivansiu.com/blog/2014/05/01/os-x-reveal-file-in-console

One of the neat things you can do in OS X is to reveal a file in Finder.app from some other applications. Turns out lots of the time, we also want to do that in the terminal. The following script helps you with that:

on run args
  set fullpath to do shell script "realpath " & (quoted form of first item of args)
  set theFile to POSIX file fullpath
  tell application "Finder"
      reveal theFile
  end tell


  1. You should put this into a directory in your search path. I recommend in ~/bin. Also remember to chmod +x.
  2. The above requires another script realpath, which returns the fullpath of a file. You can find it here.
<![CDATA[OS X: get full path of file using realpath]]> 2014-05-01T18:25:56-05:00 http://blog.ivansiu.com/blog/2014/05/01/os-x-get-full-path-of-file-using-realpath
Demonstrate of realpath
➜  /Applications  realpath iBooks.app
➜  /Applications

realpath is a command line utility that is included in most UNIX distributions but not Mac OS X. Thanks to Stuart Campbell, a minimal implementation is provided here, and my fork.

If you use homebrew, you can tap my repo, and install it using homebrew.

brew tap iveney/mocha
brew install realpath

Viola! Now you can get the full path of file in console. A nice thing I often use is to chain it with pbcopy to copy the full path to the OS X clipboard.

<![CDATA[Send ctrl-a in tmux after rebinding to it]]> 2014-05-01T17:14:46-05:00 http://blog.ivansiu.com/blog/2014/05/01/send-ctrl-a-in-tmux-after-rebinding-to-it

While tmux provides much better functionality than screen, most of us that work with tmux have been using screen for a long time, and it is more comfortable for us to use ctrl-a than the default ctrl-b, which is finger-strechy. Thus the first thing I will do after installing tmux is to rebind the prefix to ctrl-a. That gives us the most handy way of swapping last two windows by typing ctrl-a ctrl-a.

However, this comes for a price. That is, in a shell environment that is integrated with readline, ctrl-a is used to jump the begining of line. Now that it is mapped as prefix, we can no longer do that.

Surprisingly, the solution is pretty simple. Just use ctrl-a a to send the prefix itself, and use ctrl-a ctrl-a to go to the last window. Specifically, add these two lines in ~/.tmux.conf:

bind a send-prefix
bind-key C-a last-window


<![CDATA[Source-highlight for matlab/octave]]> 2014-05-01T01:59:40-05:00 http://blog.ivansiu.com/blog/2014/05/01/source-highlight-for-matlab-slash-octave

I recently worked with Matlab a lot. When in console, sometimes I want to use less to quickly examine the file content, and I have already set it up such that it uses source-highlight to output colorful escape sequence to the console. However, source-highlight does not come with a syntax support for Matlab by default. Luckily, this post and this (in Chinese) provides a solution.

First of all, install source-highlight using homebrew.

brew install source-highlight

Note that source-highlight depends on boost, and as of the date of this post, brew provides a precompiled library (bottle) for boost. However, the python support is compiled against the system python, so if you installed a custom one (say installed via homebrew) and use it by default, brew will compile the boost from source instead, which takes an extremely long time. To prevent this, we need to unlink it first, and link it back afterwards. That is,

brew unlink python
brew link python    # after installation

Go to the following folder and create two files,

cd `brew --prefix source-highlight`/share/source-highlight
keyword blue;
string #a020f0;
comment darkgreen;
keyword = "break|case|catch|classdef|continue|else|elseif|end|for|function|global|if|otherwise|parfor|persistent|return|spmd|switch|try|while"

keyword = '^\s*(break|case|catch|classdef|continue|else|elseif|end|for|function|global|if|otherwise|parfor|persistent|return|spmd|switch|try|while)(?=\s)'

include "function.lang"

state command start '^\s*[a-zA-Z][\w]*(?=\s)(?!\s+\.?[*/+-:]\s+\w)(?!\s+=)' begin
        comment start "%"
        string delim '[[:blank:]]' '[^%;]*'

comment delim "%{" "%}" multiline nested
comment start "%"

string delim '(?<![\w.])\'' "'" escape "''"

Finally, edit lang.map to create a mapping for matlab file.

echo 'm = matlab.lang' >> lang.map
<![CDATA[Batch remove photos in iPhone, batch convert videos and upload back]]> 2014-01-29T20:16:21-06:00 http://blog.ivansiu.com/blog/2014/01/29/batch-remove-photos-in-iphone One of the problems that drives iOS user crazy is the user-unfriendly manipulation/syncing of photos in iOS. There are just no easy way to remove photos in batch (though you can delete the entire camera roll in the settings).

There are several ways to manipulate it, but really not enough:

  1. use iPhoto/Aperture to import and delete. However, the photos must be imported first, I cannot just delete it. Ever since there is iCloud, importing becomes not that important.
  2. use iTunes to Sync. Same as above, ever since iCloud, no reason to sync again.
  3. the only way to use built-in tools to manipulate the camera roll is to use Image Capture utility. That way, one can select and delete photos. However, it still does not have custom filtering of photos and does not support albums.

The workflow I adopted is a two-step approach: mark those I want to keep in the iPhone, delete all stuff using the 3rd method, then upload back.

If you have some videos that occupy lots of space, you can convert them to lower quality. To do this, HandBrake is the excellent tool, which is open-sourced. However, it does not support batch change. Luckily, HandBrakeBatch by OSOMAC can achieve this.

To upload things back, SimpleTransfer can help, especially for videos, which cannot be put back into camera roll easily (I have no idea why apple restricts this). The lite version is free, but you can only upload one item at a time, and there are also some restrictions.

<![CDATA[Fix (ugly) Safari 7.0 not using local pac file]]> 2013-12-05T02:03:43-06:00 http://blog.ivansiu.com/blog/2013/12/05/fix-ugly-safari-7-dot-0-not-using-local-pac-file I found that Safari in Mavericks is not using local proxy.pac at all. Turns out because of sandboxing, it will not allow reading file from local. A traditional solution is to turn on Web Sharing, and thus use HTTP to read the pac file such as http://localhost/proxy.pac.


sudo apachectl start



<![CDATA[LaTeX Tips and Tricks Collection]]> 2013-12-03T15:18:00-06:00 http://blog.ivansiu.com/blog/2013/12/03/latex-tips-and-tricks-collection This post summarizes some common useful tips in LaTeX editing.


  • Horizontal alignment of subfigures
  • subfloat in subfig
    % Style: Figure 1(a)



  • Graphics path
  • Use other file extensions:
    \DeclareGraphicsExtensions{.pdf, .jpg, .png}

Table and Tabular

  • threeparttable: Use footnote in tabular
    % inside tabular:
    % after tabular
    \begin{tablenotes}[para] % do not break line between items
    \item [$\dagger$] A foot note. % this reference to the item

Theorem, Definition

  • New definition/theorem
  • Useful packages:
    • ntheorem
    • amsthm



  • csvsimple: can automatically read csv and create tabular.
  • algpseudocode: the most updated algorithm / code environment, need to sit inside with algorithm package.
  • biblatex: provides better control for Bibliography.
  • multirow: provides \multirow and \multicolumn.
  • url: provides \url.
  • xspace: prevent a command eating space.
  • flushend: provides \flushend, balance two columns.

Controlling space

Commands and tools:

  • latexmk: automatically compile multiple times to resolve reference.
  • biber: replacement for bibtex for biblatex
  • texdoc: use texdoc <package> to search for a manual.


  • proof: use \IEEEproof
  • multiple equations: use \IEEEeqnarray or array.


<![CDATA[Saving $80 by Fixing MagSafe by Yourself]]> 2013-11-08T22:06:00-06:00 http://blog.ivansiu.com/blog/2013/11/08/saving-80-dollars-by-fixing-magsafe-by-yourself After four years of use, the wire on my MagSafe finally fray out. After searching a bit, I found that a new one costs $80!! My old memories came back: almost all accessories by Apple are rip-offs. See how low the ratings are:

I know that this can be easily fixed if you know a little soldering and have courage: the adapter is working perfectly fine, it is just the wires. I decided to DIY. There are several pretty good articles on how to open the MagSafe and how to solder it.

The following are my workflows. The first step is to open it. You can see there are two wires, in fact in my case only the black wire is broken. I don’t even need to solder.

Okay, go ahead and twist them. Use insulating tapes to wrap them tight.

Finally, reassemble it and use more tapes, since the outside layer is cut out. More importantly, strong taping help to protect another fray.

It looks a bit odd though, since the Apple product is supposed to be WHITE. Here’s how I fix it. I don’t have good tools available, so I just use whatever I have. I recalled that I have some Google stickers, and I just cut the white pieces out.

After more taping, it looks like better now. Maybe I should consider wrapping better things outside later.

Hooray! Now it is working again! In fact, I am amazed that this piece of gadget has been working for four years, daily. It is still working just fine :)

