台中六日总结

来了台湾六天没时间出去玩不知道算不算杯具。每天早上八点去后里,好几天晚上都是加班到十点才回台中的旅馆,工作加路程耗时足足有十四个小时,每天爽到死。这也是我宁愿在家呆着的原因。

本来说如果有时间去附近的景点转转,不过公司安排明天走人,也就算了。从台北飞的机票订不到了,只有坐高铁从高雄走。

只是有几天晚上出去逛了逛,关键词是:夜市,水手服学生妹,槟榔西施,八家将,补习班,棒球,太阳饼,公交车车身上司机的名字。

中华路夜市

中华路夜市

台中火车站

日治时代的台中火车站,现在还在使用。台湾各地都有这样的火车站。

Read More »

MATLAB 与 C 语言混合编程接口:MEX 函数最简单示例之一

MATLAB是一种解释性语言,不需要编译,调试比较方便,但是缺点是速度慢。这一点在执行复杂的科学算法的时候体现极为明显。而C语言虽然相对比较复杂,但是执行效率很高,MATLAB很多内置函数都是用C写的。另外有时候很多算法已经已C语言的形式写好,于是我们会想到是否有方法将C语言代码与MATLAB连接起来。MATLAB提供一个C语言中的MEX函数库,可以实现以上功能。这里以一个最简单的例子来说明。

我们的目标是:用C语言写一个加法函数add(),在MATLAB中输入c=add(a,b)可以得到a与b的和。

这个示例是否有点白痴?c=a+b不就完了?这里只是一个示例而已,把最基本的环节解释清楚就够了。

我们要做的是

  1. 在MATLAB当目录中建立一个add.c文件;
  2. 用你熟知的C语言写一个add()函数;
  3. 利用mexFuncion()函数创建C与MATLAB的接口;
  4. 从MATLAB命令窗口中编译add.c文件为MEX文件;
  5. MATLAB命令窗口中使用add()函数。

建立add.c文件

这个文件被称为Source MEX-File

  1. 在当前文件夹窗口中新建一个脚本:右键单击空白处,选择New File,选择Script
  2. 重命名文件为add.c
  3. 用外部编辑器打开add.c

编辑add.c文件

MATLAB提供一个函数库,保存在mex.h中,所以文件一开始要将其include:

1
#include "mex.h"

然后用你熟知的C语言写一个函数吧

1
2
3
double add(double x, double y) {
    return x + y;
}

这段代码被称作Computational Routine,就是真正的算法实现的地方。

然后我们来建立其与MATLAB的间接口。MEX函数库里有个mexFunction()函数,它相当于C语言中的main()函数。所以这里我们知道了MEX源文件没有main(),而是以一个mexFunction()代替。

mexFunction的参数是这样的:

1
2
3
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    //这里是正文
}

其中nlhs (number of left-hand side) 是输出参数的个数,nrhs (number of right-hand side) 是输入参数的个数。例如对于c=add(a,b),有 nlhs=1,hrhs=2。

plhs[]与prhs[]都是指针数组,也就是说它是个数组,每个元素都是一个指针,这些指针指向的东东的类型是mxArray。那什么是mxArray呢?可以把他理解MATLAB中的矩阵,因为MATLAB中所有数据都是以矩阵的形式保存的。

先讲prhs[],就是输入的参数,prhs[0]指向a,prhs[1]指向b,但是注意不能用*(prhs[0])得到a的值。因为prhs[0]指向的东西的类型是mxArray(参数列表里看出),想把它的值以我们常用的数值形式赋给一个标量(Scalar),得使用mxGetScalar()函数转化一下:

1
2
3
    double a, b;
    a = mxGetScalar(prhs[0]);
    b = mxGetScalar(prhs[1]);

plhs对应的输出的内容。plhs[0]这个指针指向输出的第一个参数,就是c=add(a, b)中的c了。记住这个c应该是以mxArray的类型出现的,为了得到mxArray类型的输出量,要使用mxCreateDoubleMatrix()函数,它创建一个指向mxArray类型的指针。

1
    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);

参数(1, 1, mxREAL)定义了对应c的尺寸类型,MATLAB中c是以1×1的实数矩阵形式报保存的。

而使用mxGetPr()函数可以得到plhs[0]指向的mxArray的第一个double类型的指针。

1
2
    double *c;
    c = mxGetPr(plhs[0]);

最后调用add()函数

1
    *c=add(a,b);

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "mex.h"

double add(double x, double y) {
    return x + y;
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    double a, b;
    a = mxGetScalar(prhs[0]);
    b = mxGetScalar(prhs[1]);

    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);

    double *c;
    c = mxGetPr(plhs[0]);

    *c=add(a,b);
}

编译add.c文件为MEX文件

在MATLAB命令窗口中输入

1
mex add.c

回车后MATLAB会调用编译器把源程序编译成为MEX文件。
注意如果是在MAC OS X下提示gcc 4.0 Command not found之类的错误信息,则需要安装Xcode

执行c=add(a,b)

在MATLAB命令窗口中输入

1
c=add(1, 2)

回车后可以得到结果。

注: MATLAB 2010a 及以后版本使用了不同的 API,所以该文章适用于以前的版本。

安装 Xcode 3.2

学习一种新的计算机语言不能只看书本,实践是最好的老师。实践的前提是得有实践的条件。以前学 C,就得安装个Turbo C;学 VB, VC, 就得安装个 Visual Studio。想学 Mac OS X 的编程也得首先建立开发环境。

首先介绍一点 Mac OS X 开发常识。

  • Mac OS X 里的很多程序是利用 Cocoa 开发环境(或者说是一种 API)编写;
  • 使用的语言叫 Objective C;
  • 利用的软件叫 Xcode。

简单地说,如果你想学习如何编写一个 Mac OS X 下的应用程序,则首先得安装 Xcode。Xcode 的安装包可以从 Apple 官网下载,不过鉴于安装包也不小,如果你有 Mac OS X 的安装 DVD(或其 DMG 镜像)的话,可以直接利用 DVD 安装。这里以 Snow Leopard 10.6.3 的 DMG 为例。

  1. 双击 DMG 文件装载安装磁盘,启动“可选安装”文件夹里的 Xcode 安装器;
  2. 一路点“继续”直到完成安装。大概有 Xcode 大小有 2G。

这样长征的第一步就走完了,启动 Xcode (/Developer/Applications/Xcode) 熟悉熟悉界面吧,虽然看得一头雾水。

重新设置 WordPress 自增数字编号的值

之前这个博客有个不是问题的问题。Wordpress 的每篇文章都有个数字编号(ID),我这里由于以前数据导入的问题,导致ID 不是按时间顺序排列,加上之前又使用了一个 Lifestream 插件,它每抓取一条信息就会占用一个 ID,以至于一共只有 100 来篇的文章最新的 ID 达到了近 10000。

我手动删除了 Lifestream 插件和数据库里的相关内容。然后半手动地重新排列了一下ID顺序。这是出现一个问题:即使表面上看起来最新的文章 ID 是 100 多,但如果新增一篇文章,自动产生的ID仍然有近一万。也就是说,数据库一定记录下了产生的最大 ID,并且在它的基础上增加新的记录。

经过 Google,我找到了将这个最新 ID 设置到想要的任意数字的方法:进入 phpmyadmin,进入 wp-posts 表,输入以下 SQL 命令

1
ALTER TABLE wp_posts AUTO_INCREMENT={当前最新的一篇文章的数字ID}

例如,最新文章ID是100,则把上面的{当前最新的一篇文章的数字ID}换为100即可。

注意,AUTO_INCREMENT小于目前最大的ID,则不能达到需要的效果。

Adium 实用配置笔记

Adium 是 Mac OS X 下最出色的即时通讯整合客户端。一直以来我很少使用除 QQ 以外的聊天工具,虽然有 MSN 和 Google Talk,无奈上面的好友太少,每次开机时启动一堆聊天工具也很占系统资源,而常开的 QQ 上由于好友太多以至于常年隐身。这样的结果是让人感觉我似乎很少使用聊天工具(其实认识的大多数人都是处于这种状态)。不过自从开始使用 Adium 以来,我很乐意把它设置为开机启动并自动登录,和一些在国外的朋友交流得也逐渐增多。而且随着使用的增多,我发现它的与 Mac OS X 等整合、扩展功能与自定义能力越来越强。

所支持的帐号

我主要使用 Adium 登录 MSN,Google Talk,Facebook,以及飞信。其中飞信目前还需要使用插件才能支持。另外一般人可能还会用到的帐户有 Yahoo Messenger,Myspace IM,以及使用 XMPP 协议的客户端(理论上人人桌面也是可以的,但是还没弄成功过)。

有一点需要注意,虽然 Adium 声称原生支持 QQ 登录,但是本人试过一次,登录后不久自动退出,提示帐号出现异常,需要重现修改密码才能登录。这个费了我半天功夫才弄回 QQ 密码,所以强烈建议暂时不要用 Adium 登录 QQ

从 1.4 版开始支持 Twitter,但是功能还很有限,所以我很少使用。

添加帐号的方式:文件》添加帐号,然后选择一个 IM 类型再填入登录信息就 OK。

关联用户名到地址簿

如果使用 Mac OS X 的地址簿(Address Book)整理联系人,可以很方便的管理信息。这样的一个好处是,如果在地址簿里有某个人的 IM 帐户记录,则在 Adium 里面会自动关联。

比如如果你在地址簿里有个联系人叫 Steve Jobs,他平时使用多个 IM 帐号,例如steve.jobs@msn.com(MSN),steve.jobs@gmail.com(Google Talk)等。通常情况下我们会分别登录 Windows Live Messenger 和 Google Talk 客户端,可能发现他的昵称很难记住,于是手动更改昵称为他的姓名。如果用 Adium 绑定你的两个帐号,Adium 会自动从地址簿里搜索 IM 记录找到联系人,然后用联系人的姓名更替 IM 上的昵称。

这样的好处就是,所有 IM 的联系人的管理操作都可以转移到地址簿里进行。

默认联系人中文姓名颠倒问题

默认情况下,Adium 从地址簿里读取联系人姓名,并按照“名 姓”的西方惯例显示。我曾以为这个无法设置,所以手动更改每个联系人。这样就体现不出 Adium 的优势了。其实这里是可以设置的。

菜单栏 » Adium » 偏好设置 » 高级 » 地址簿,将自地址簿输入我的联系人姓名打钩, 将格式名称改为“姓 名”。

Adium Name from Address Book

位于屏幕边缘时自动隐藏

QQ 有个很好的功能就是能够自动“吸入”屏幕边缘。在 Adium 也可以实现,不过似乎只能两侧,上方是不行的:

菜单栏 » Adium » 偏好设置 » 高级 » 联系人列表,自动隐藏联系人列表选“在屏幕边上”。