2011年5月27日星期五

数码单反(DSLR)相机raw格式图片的读取和处理

随着消费用数码单反(DSLR)相机成本的下降和性能的提升,在很多要求不太高的科研场合DSLR相机可以用作昂贵的高档CCD数码相机的替代品。现在最新的数码相机可以提供14位A/D转换,而动态范围可以到达11档光圈以上【参考链接:12】,很多时候这已经可以满足要求了。一般摄影爱好者使用的JPEG图片格式只能存储8位的层次,而且JPEG图片压缩过程中会有失真,所以作为科研使用的DSLR相机必须使用raw图片格式。

一般各个消费用相机厂商都使用自己专有的raw格式,所以处理起来不像科研级相机那么直接。dcraw是一个Linux平台上的能将各主要品牌相机的raw格式图片转为Netpbm格式图片的小工具。Netpbm提供了一些工具软件,另外很多图像处理软件也包含对Netpbm格式的支持,所以可以在此基础上对图片进行进一步处理。

很多时候我们可能希望自己写代码来处理图片,因为:
  1. 很多图像处理软件只支持8位(或24位RGB)而不支持16位图片;
  2. 科研上用到的算法大都比较复杂,现有的软件不满足需求。
Netpbm可以把图片存成二进制文件或者纯文本(ascii)文件。无论哪种方式,开始的几行都是标识文件格式的纯文本信息,后面跟着是文件内容。

纯文本文件的好处是数值大小一目了然,但是文件比较大。二进制文件比较小,但是处理的时候需要注意:Netpbm存储文件时使用的是Big-endian方式,而一般x86机器都是使用Little-endian方式,所以在读取数据时要进行转换。glibc的endian.h提供这样的转换函数。二进制文件存储顺序是从上到下按行存储,每行内按从左到右顺序存储。

dcraw转换图片时默认使用8位方式,如果要使用16位方式,需要使用参数 -6

2011年5月24日星期二

《Maxima快速参考手册1.1》

这是之前写的一份Maxima中文文档的更新版本。

2011年4月15日星期五

Vim笔记(二)

  1. 分割窗口
    :split file2    把窗口分割成上下两半,在新开窗口打开文件file2
    :new    上下分割窗口,在新开窗口打开新文件
    CTRL-W w    切换窗口
    CTRL-W +    增大窗口尺寸
    CTRL-W -    缩小窗口尺寸
    :vsplit file2    左右分割窗口,在新开窗口打开文件file2
    CTRL-W h    切换到左边窗口,其他方向按j, k, l类推
    CTRL-W H    移动窗口到最左边,其他方向按J, K, L类推
    :qall    退出所有窗口,类似的有:wall
  2. 反复执行复杂命令
    q{register}    开启寄存器,开始记录命令,register可以是az中任何一个
    q    结束记录命令
    @{register}    执行寄存器{register}内所有命令
  3. 查找替换一段字符
    :[range]s/from/to/[flags]    将from替换为to[range]控制替换范围,[flags]表示一些控制参数
    常用[range]
    • .    当前行
    • $    文件最后一行
    • 1,5    第一行到第五行
    • %    全部文件
    • .+3    当前行之下第三行
    常用[flags]
    • g    替换所有匹配字符串,否则只替换第一个匹配
    • c    执行每一个替换之前寻求确认
  4. 可视化块模式
    CTRL-V    开启可视化块模式,用h,j,k,l选择块
    I{string}<Esc>    在块的左边每一行插入一段字符串
    A{string}<Esc>    在块的右边每一行加入一段字符串
    c{string}<Esc>    替换一个块的文字
    U    换为大写字母
    u    换为小写字母
    ~    大小写互换
  5. 数行合并
    J    数行合并,去除换行符

2011年4月14日星期四

Vim笔记(一)

常用的Vim命令小结,最基本的就不说了,例如如何安装,如何启动和退出,两种基本模式(正常模式和插入模式),用h,j,k,l移动光标,简单的复制粘贴等等。
  1. 移动光标
    1. 以字符为单位
      f    右移至指定字符,例如fh移动至右边第一个h
      F    左移至指定字符
    2. 以词为单位
      w    右移至词首
      b    左移至词首
      e    右移到词尾
      ge    左移到词尾
    3. 以行为单位
      0    左移至行首
      ^    左移至行首第一个非空字符
      $    右移至行尾
      gg    移动至第1行
      G    移动至最后1行
      nG    移动至第n行
      n%    移动至n%位置
    4. 以屏为单位
      H    移动至屏幕顶端
      M    移动至屏幕中间
      L    移动至屏幕底端
      CTRL-U    向上滚半屏
      CTRL-D    向下滚半屏
      CTRL-F    向下滚一整屏
      CTRL-B    向上滚一整屏
  2. 简单搜索
    /string    向后搜索字符串
    ?string    向前搜索字符串
    n    下一个匹配字符串
    N    上一个匹配字符串
    /\<word\>    匹配整个单词,\<\>分别匹配词首和词尾
    %    寻找匹配的括号
  3. 书签
    ma    标记此处为a,共可使用az二十六个书签
    `a    回到标记为a

2011年3月4日星期五

几个关于Gnuplot小技巧的网页

Gnuplot手册不能告诉你的小技巧。Gnuplot也可以画出很惊艳的图片。
  1. not so Frequently Asked Questions
    http://t16web.lanl.gov/Kawano/gnuplot/index-e.html
  2. Gnuplot tricks blog
    http://gnuplot-tricks.blogspot.com/
  3. Impossible gnuplot graphs
    http://www.phyast.pitt.edu/~zov1/gnuplot/html/intro.html
  4. Gnuplot surprising
    http://gnuplot-surprising.blogspot.com/
  5. Gnuplotting
    http://www.gnuplotting.org/

2011年1月12日星期三

Octave笔记

Octave可以看作是开放源代码版本的Matlab,它的命令几乎和Matlab完全一样,因此可以用Matlab的书籍和文档来学习Octave。另外,绝大多数Matlab的代码也可以不经修改在Octave中运行。对于初学者来说,下面这些笔记可以帮助快速上手Octave。更多的功能,可以参考Octave文档或者其他Matlab的资料。
  1. 脚本文件,以下面一行开始:
    #!/usr/bin/octave -qf
  2. 注释,以%或者#开始
  3. 虚数单位:i, j, I, J都可以 两种方法定义复数:3 + 4i或者complex(3, 4)
  4. 定义矩阵:
    octave:1> a = [1, 2; 3, 4]
    a =
    
    1   2
    3   4
  5. 随机数:rand()或者rand(m, n)
  6. 定义一段连续序列:
    octave:1> 1:5
    ans =
    
    1   2   3   4   5
    还可以指定步长:
    octave:2> 1:2:10
    ans =
    
    1    3    5    7    9
  7. 字符串:单引号或者双引号
  8. 定义Data Structure:
    octave:1> x.name = ”Yusuf”
    octave:2> x.age = 33
    octave:3> x.phone = “46103”
    octave:4> x
    x =
    {
    name = Yusuf
    age = 33
    phone = 46103
    }
  9. 定义Cell Array:
    octave1:> a = {”random matrix”, rand(2)}
    a =
    
    {
    [1,1] = random matrix
    [1,2] =
    
    0.417140   0.460380
    0.337105   0.078835
    
    }
    
    octave2:> a{2}(1,2)
    ans =  0.460380
  10. 声明全局变量:
    global c = 3e8
  11. 算术符号
    x + y 加法
    x - y 减法
    x * y 矩阵乘法
    x .* y 元素相乘
    x / y 右除,相当于(inverse (y’) * x’)’
    x ./ y 元素右除
    x \ y 左除,相当于inverse (x) * y
    x .\ y 元素左除,每个y元素被相应的x元素除
    x ^ yx ** y 乘方
    x .^ yx .** y 元素乘方
    x’ 转置复共轭
    x.’ 转置
  12. 比较符号
    x < y 小于
    x <= y 小于等于
    x == y 等于
    x >= y 大于等于
    x > y 大于
    x != yx ~= y 不等于
  13. if语句
    • 形式一:
      if (condition)
        then-body
      endif
    • 形式二:
      if (condition)
        then-body
      else
        else-body
      endif
    • 形式三:
      if (condition)
        then-body
      elseif (condition)
        elseif-body
      else
        else-body
      endif
  14. switch语句
    switch expression
      case label
        command_list
      case label
        command_list
      …
      otherwise
        command_list
    endswitch
  15. while语句
    while (condition)
      body
    endwhile
  16. do-until语句
    do
      body
    until (condition)
  17. for语句
    for var = expression
      body
    endfor
  18. 定义函数
    • 形式一:无自变量 function name body endfunction
    • 形式二:带自变量 function name (arg-list) body endfunction
    • 形式三:单个返回值 function ret-var = name (arg-list) body endfunction
    • 形式四:多个返回值 function [ret-list] = name (arg-list) body endfunction
  19. 可变自变量长度函数 function val = smallest (varargin) val = min ([varargin{:}]); endfunction
  20. 函数Handles(指向函数的指针) @function-name
  21. 匿名函数 @(argument-list) expression
  22. 终端输出 disp (x)
  23. 写读包含分隔符的数据文件 dlmwrite (file, a) dlmwrite (file, a, delim, r, c) dlmwrite (file, a, key, val ...) dlmwrite (file, a, "-append", ...) a是待写矩阵,delim是分隔符,默认为逗号。r, c分别为起始的空行和空列。key包含下列参数:
    • "append" 即上面的"-append","on"或者"off"
    • "delimiter" 即上面的delim
    • "newline" 换行符
    • "roffset" 即上面的r
    • "coffset" 即上面的c
    • "precision" 精确度,可以用类似fprintf的格式字符串,或者有效数字位数
    data = dlmread (file) data = dlmread (file, sep, range) range为四元素的矢量:[R0, C0, R1, C1],为数据块左上角和右下角的标记,从0开始
  24. Octave可以使用大多数类似C的I/O函数(fprintf,fopen等)
  25. 常用数学函数
    exp (x)指数函数sinh (x) 双曲正弦
    log (x)自然对数cosh (x) 双曲余弦
    log10 (x)以10为底的对数 tanh (x) 双曲正切
    log2 (x)以2为底的对数 coth (x) 双曲余切
    sqrt (x) 平方根 sech (x) 双曲正割
    abs (z) 绝对值 csch (x) 双曲余割
    arg (z) 辐角 asinh (x) 反双曲正弦
    conj (z) 复共轭 acosh (x) 反双曲余弦
    real (z) 复数实部 atanh (x) 反双曲正切
    imag (z) 复数虚部 acoth (x) 反双曲余切
    sin (x) 正弦 asech (x) 反双曲正割
    cos (x) 余弦 acsch (x) 反双曲余割
    tan (x) 正切 sum (x) 求和
    cot (x) 余切 prod (x) 求积u
    sec (x) 正割 ceil (x) 不小于x的最小整数
    csc (x) 余割 floor (x) 不大于x的最大整数
    asin (x) 反正弦 factorial (n) 阶乘
    acos (x) 反余弦 max (x) 最大值
    atan (x) 反正切 min (x) 最小值
    acot (x) 反余切 round (x) 四舍五入
    asec (x) 反正割 sign (x) 符号函数
    acsc (x) 反余割
    atan2 (y, x) 计算atan (y / x)
    sind (x),… 以度数为单位的三角函数
  26. 特殊函数
    [a, ierr] = airy (k, z, opt) Airy函数
    [j, ierr] = besselj (alpha, x, opt) 第一类Bessel函数
    [y, ierr] = bessely (alpha, x, opt) 第二类Bessel函数
    [i, ierr] = besseli (alpha, x, opt) 变形第一类Bessel函数
    [k, ierr] = besselk (alpha, x, opt) 变形第二类Bessel函数
    [h, ierr] = besselh (alpha, k, x, opt) 第一类(k=1)和第二类(k=2)Hankel函数
    beta (a, b) Beta函数
    gamma (z) Gamma函数
    bincoeff (n, k) 二项式系数
    erf (z) 误差函数
    legendre (n, x, normalization) n阶Legendre函数,m = 0…n
  27. 线性代数
    det (a) 行列式
    eig (a) 本征值
    dot (x, y) 点乘
    inv (a) 逆矩阵
  28. 解非线性方程 [x, fval, info] = fsolve (fcn, x0, options) fcn是包含待解方程组的函数,x0是自变量初始值,x为返回的数值解,fval为返回的函数值,如果结果收敛,info为1,否则为其他值。例子: function y = f (x) y(1) = -2*x(1)^2 + 3*x(1)*x(2) + 4*sin(x(2)) - 6; y(2) = 3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4; endfunction [x, fval, info] = fsolve (@f, [1; 2]) 结果: x = 0.57983 2.54621 fval = 6.1872e-08 -3.2708e-07 info = 1
  29. 数值积分(各函数对应不同算法) [v, ier, nfun, err] = quad (f, a, b, tol, sing) quadl (f, a, b, tol) quadgk (f, a, b, prop, val, ...) quadl (f, a, b, tol)

2010年1月21日星期四

统计笔记(一)

  1. 协方差(covariance)定义:
    Cov( Y1 , Y2 )=E[( Y1 - μ1 )( Y2 - μ2 )]

    其中 E()表示期望值, μ1 =E( Y1 ) μ2 =E( Y2 )
  2. 相关系数(coefficient of correlation)定义:
    ρ= Cov( Y1 , Y2 ) σ1 σ2

    其中 σ1 σ2 分别是 Y1 Y2 的标准差。
  3. 任意分布样本的平均值
    Y1 Y2 ,..., Yn E( Yi )=μ V( Yi )= σ2 的独立随机变量,则平均值
    Y ¯ = 1 n i=1 n Yi

    的期望值 E( Y ¯ )=μ,方差 V( Y ¯ )= σ2 /n
  4. 正态分布样本的平均值
    Y1 Y2 ,..., Yn 是来自正态分布(期望值为 μ,方差为 σ2 )的样本,其平均值
    Y ¯ = 1 n i=1 n Yi

    也呈正态分布,期望值 μ Y ¯ =μ,方差 σ Y ¯ 2 = σ2 /n
  5. Y1 Y2 ,..., Yn 同上,那么
    i=1 n Zi 2 = i=1 n ( Yi -μ σ )2

    呈自由度为 n χ2 分布。
  6. Y1 Y2 ,..., Yn 同上,那么
    (n-1) S2 σ2 = 1 σ2 i=1 n( Yi - Y ¯ )2

    呈自由度为 n-1 χ2 分布。其中,
    S2 = 1 n-1 i=1 n( Yi - Y ¯ )2

    是样本方差。 S2 Y ¯ 为独立随机变量。
  7. 学生 t分布(简称 t分布)定义:
    如果 Z是正态分布随机变量, W是自由度为 ν χ2 分布随机变量,如果 Z W互相独立,则
    T= Z W/ν

    呈自由度为 ν t分布。
  8. 在上面的定义中,如果让 Z=n( Y ¯ -μ)/σ W=(n-1) S2 / σ2 ,则由上面第4和第6条结论可以得出
    n( Y ¯ -μ S )

    呈自由度为 n-1 t分布。
  9. F分布定义:
    如果 W1 W2 为独立 χ2 分布变量,自由度分别为 ν1 ν2 ,则
    F= W1 / ν1 W2 / ν2

    被称作具有 ν1 分子自由度和 ν2 分母自由度的 F分布。
  10. 中心极限定理(Central Limit Theorem)
    Y1 Y2 ,..., Yn 是独立的具有同样分布的随机变量,期望值 E( Yi )=μ,方差 V( Yi )= σ2 <。定义
    Un =n( Y ¯ -μ σ )

    其中
    Y ¯ = 1 n i=1 n Yi

    那么,当 n时, Un 趋近于正态分布。

2010年1月18日星期一

写了一份Maxima的中文文档

以前我为计算机代数系统Maxima写了一些简介,这次抽时间写了一个比较完整的中文文档,希望能为开放源代码软件的推广做点贡献。

《Maxima快速参考手册》 写的仓促,欢迎反馈。

2009年5月11日星期一

在eps图片上添加LaTeX公式

利用MetaPostexteps宏包,可以在metapost文件中加入eps图片,同时利用metapost的label命令在图片任何地方加入LaTeX公式。下面是一个使用exteps的例子:
input exteps
verbatimtex
\documentclass{article}
\begin{document}
etex
prologues:=2;
beginfig(1);
begineps "figure.eps";
endeps;
label.rt(btex $f(x) = \sqrt x$ etex, (2cm,3cm));
endfig;
end
为了使用LaTeX命令,需要设置环境变量
TEX=latex

2009年4月2日星期四

GnuPlot在PostScript终端下使用任意字体

有时候我们在GnuPlot中想使用一些其他字体,例如LaTeX字体或者一些艺术字体,这时候我们可以用fontfile选项把自己的字体内嵌进生成的PostScript文件:
set term postscript fontfile "myfont.ext" "FontName"
这里的字体可以是Type 1字体,也可以是TrueType字体。命令必须包含完整字体文件名,包括扩展名。字体文件可以在当前目录,也可以用GNUPLOT_FONTPATH环境变量控制字体路径。FontName(字体名)不是字体文件名,通常不那么容易直接得到,尤其是TrueType字体。最简单的办法是在GnuPlot里执行
set term postscript fontfile "myfont.ext"
GnuPlot会自动给出字体名。

这样,由于可以使用LaTeX字体,配合PostScript终端的enhanced选项,我们几乎可以在GnuPlot中输入任意特殊字符。另外,为使用TrueType字体,需要安装ttf2pt1工具进行字体自动转化。

2009年3月16日星期一

sed编辑器的使用

sed被称为流编辑器(stream editor)。它和一般写字板之类的文本编辑器不同,它通过逐行读入文本文件,按照用户指定的方式对文本进行过滤。用户通过脚本命令告诉sed该如何处理文本文件,所以sed可以看作一种程序语言。这看起来没有使用鼠标和键盘编辑文件的编辑器方便,但是当我们需要自动处理大量文本文件时,这会非常方便。 例如,我需要把很多数据文件的某些行注释掉,也就是在所有数据文件的某几行开始处加上字符“# ”。如果一个个文件编辑,工作量就太大了。下面这个命令可以很方便的实现这个功能:
sed -i '1,5 s/^/# /' *.txt
这个命令把每一个.txt作为后缀的文件前5行开始处加上“# ”。 下面把常用的一些sed命令总结一下。
  1. 替换一段文字
  2. 这个恐怕是sed最常用的方式了。
    sed 's/a/A/' <old >new
    这个命令把文件old中的小写字幕a换为大写字幕A,并且把新的文件存为new。但是这个命令只能替换第一个a,如果想要把文件old中所有的a都替换掉,需要加上一个参数:
    sed 's/a/A/g' <old >new
    上面命令中的斜杠/是分隔符,但是sed没有要求一定用斜杠作为分隔符,其实可以用任何字符(只要不和搜索字符矛盾)作为分隔符,例如冒号等等。
  3. 执行多个命令
  4. 上面的例子中只执行了一个命令,如果需要同时执行多个命令,需要用到参数-e
    sed -e 's/a/A/' -e 's/b/B/' <old >new
  5. 指定对某些行操作
  6. 如果只对某些行进行操作,可以像一开始举的例子那样,使用行号指定范围:
    sed '1,10 s/A/a/'
另外,这里有一个很有用的sed常用单行命令参考

2009年1月9日星期五

GnuPlot使用png terminal时找不到字体的问题

GnuPlot不同的终端(terminal)使用不同的处理字体的方法。png/jpeg/gif使用libgd,所以字体目录由GDFONTPATH这个环境变量控制,可以直接使用TrueType字体。例如把需要用到的字体放在$HOME/fonts目录下,在.bashrc中添加:
export GDFONTPATH=$HOME/fonts
当路径设置好后,可以用GNUPLOT_DEFAULT_GDFONT这个环境变量设置默认字体。

2009年1月2日星期五

在USB drive(U盘)上安装Linux

UNetbootin可以很方便的把Linux装到U盘上,只要主板支持,就可以从U盘启动Linux。由于U盘可读写,比Live CD更方便。目前UNetbootin支持Fedora,Debian,Ubuntu等各种主流Linux版本。如果你的U盘比较小,可以试试Puppy Linux,挺小巧的一个Linux版本,只有100M左右大小。

2008年11月21日星期五

Mie散射计算器

Mie散射理论为球形颗粒对于电磁波的散射提供了一套严格解,其数值计算十分复杂。Bohren和Huffman的书里提供了用于数值计算的Fortran代码。另外,Oregon Medical Laser Center的网页提供了一个在线的Mie散射计算器,可以快速的计算出一些常用参数,并且给出一些图线。

2008年11月19日星期三

GNU screen的几个常用命令

GNU screen是命令行界面下的窗口管理器,允许用户在命令行界面下同时在几个虚拟窗口运行不同的程序。GNU screen有一个很有用的功能:如果用户登录到远程机器上利用screen运行程序,该程序在用户切断连接之后可以继续运行,并且下次用户可以登录继续上次的操作。下面是一些常用的命令。

首先在终端执行screen命令进入程序。执行之后虽然看不到任何变化,其实screen已经启动,我们看到的就是一个虚拟终端。
  1. 建立一个新的窗口(虚拟终端):C-a c
    也就是按Ctrl+a然后再按c
  2. 切换到之后的窗口:C-a n
  3. 切换到之前的窗口:C-a p
  4. 切换的第N个窗口:C-a N
  5. 显示现有窗口列表,用上下箭头(或者类似于vi中用j和k)移动光标,按Enter选择:C-a "
  6. 改变当前窗口的名字:C-a A
  7. 关闭目前的screen但是保留其中运行的程序(detach):C-a d
    如果直接关闭窗口也可以有同样作用。
  8. 运行screen继续上次在screen里运行的程序(reattach):screen -r
  9. 进入拷贝模式:C-a [
    在screen里不能向上翻屏,进入拷贝模式可以使用光标上下移动翻屏。用空格键可以选择要拷贝的文字,第一次按空格选择开始的字符,第二次选择结束的字符。
  10. 粘贴选择的文字:C-a ]

2008年11月16日星期日

Linux下用sopcast看电视

Sopcast是一个基于P2P技术的网络电视软件,在Linux和Windows上都可以运行。Sopcast网站提供的Linux版本倒挺简单,直接下载解压就可以用了。但是这只是一个命令行的软件。有几个图形界面可以用,觉得gsopcast不错,但是源代码在Fedora和Debian上编译都有问题,header文件需要改动几处。可能因为大家用的编译器不一样?编译好的文件在这里,是我在Debian下用gcc4.3编译的,gsopcast版本是0.4.0,可以直接下载下来用,应该不依赖特定的发行版。

如果自己在桌面建立一个gsopcast快捷方式图标的话,似乎当从图标启动的时候,$PATH变量不起作用,所以gsopcast可能找不到sopcast的执行文件。另外,新的sopcast执行文件是sp-sc-auth,而不是以前的sp-sc。要保证正常使用,最好在/usr/local/bin目录建立一个符号链接,取名作sp-sc。

2008年11月10日星期一

光圈档数(aperture stop)的计算方法

摄影的时候计算曝光量经常用到几“档”曝光这个术语。这个曝光的“档数”(stop)也经常被称作EV(exposure value)。这个“档数”到底怎么算出来的? 曝光量是由光圈和快门共同决定的。曝光量增加一倍,就叫做曝光增加一档。当光圈一定时,曝光量和快门时间(也就是曝光时间)成正比,例如1/30秒就比1/60秒曝光增加一倍,也就是增加一档。这比较容易理解。比较容易迷惑的是光圈。 光圈一般用F数(F number或者F/#)来表示,其定义为:
f/#=fD
其中f是镜头焦距,D是镜头入射孔径。如果拿起一个镜头,从前面看进去,所看到的那个圆形小孔的直径,就是镜头的入射孔径了。对于一般相机镜头,这个孔径大小是可调的,由f/#的设置来控制。有些人可能会想,既然计算曝光量,为什么不直接拿孔径大小D来算,还要定义一个什么f/#。这是因为,感光器件(胶片或者CCD)的曝光量不仅和孔径大小有关,还和焦距有关。用f/#能更准确的表示曝光量。但是这有一个前提,就是物体离镜头比较远,如果物体离镜头很近(例如显微镜),就不能用f/#来算曝光量了。这时候一个更常用的量是数值孔径(numerical aperture或NA)。 因为孔径D在分母上,所以f/#数值越小,光圈越大。例如光圈f/2比f/4要大。但是f/2并非比f/4大一档光圈,而是二档。因为镜头通光量和孔径面积成正比,也就是和孔径大小的平方成正比。所以,比f/4大一档的光圈是
422.8
实际上还会经常碰到分数表示,例如半档,1/3档。对于普遍情况下,可以用下面的公式计算两个光圈究竟差几档:
N=2log2f/#2f/#1
例如,f/1.4和f/1.8相差
N=2log2f/1.8f/1.423

2008年11月4日星期二

LaTeX CJK生成PDF文件的中文搜索以及复制粘贴

以前的blog介绍过如何在Fedora下安装配置LaTeX CJK,其他的Linux发行版也可以用类似的方法。但是如果直接用ps2pdf或者dvipdfm生成PDF文件,这样的PDF文件没办法搜索中文,也不能复制粘贴中文内容。可以用dvipdfmx将生成的dvi文件转换为PDF,这样生成的PDF可以完成上述功能。 另外,我把自己的LaTeX CJK的字体和配置文件放到了网上,地址是http://www.mediafire.com/file/dwutwxjjmdn/texmf.tar.gz,有需要的朋友可以去下载。这个文件包含CJK包和三个字体,分别是Fedora自带的文鼎宋体,楷体,还有文泉驿的黑体,应该满足大多数应用。下载后解压到$HOME目录,执行texhash $HOME/texmf。不需要进行任何其他配置。下面的文件可以用来测试安装结果:
\documentclass{article}
\usepackage{CJKutf8}
\begin{document}
\begin{CJK}{UTF8}{song}
CJK 测试。

\emph{CJK 测试。}

\textbf{CJK 测试。}
\end{CJK}
\end{document}

2008年10月31日星期五

用WebPlayer在网页里播放mp3

WebPlayer利用Flash技术,允许你在你的网页里直接播放mp3文件,而不需要任何其他软件。WebPlayer使用非常简单,只要下载一个很小的文件放在你的网站上,把要播放的mp3文件也放上去,再在你的网页的HTML文件里加几行代码,就可以了。 下面是我用口琴演奏的《天鹅》。
祝老婆纪念日快乐!

2008年10月29日星期三

光束质量因子M2(M squared)的测量

各种文献经常会用M2(M squared)因子来评价光束的质量。到底什么是M2?一般文献会告诉你,M2就是一个光束的腰半径和发散角的乘积跟TEM00高斯光束相比的比值。M2≥1,因为TEM00高斯光束的该乘积具有最小值。要想从实验得到M2的值,不可避免的要涉及光束半径测量的问题。
  1. 光束半径
  2. 光束没有明显的边界,因此它的半径有很多不同定义方法。对于高斯光束,最常见的定义就是1/e2半径,也就是把光强下降到最大值的1/e2的位置定义为半径,通常在公式里以W表示。在统计学里,我们对高斯分布的宽度(半径)使用的是方差,也就是说,对于高斯分布函数
    f(x)=ae-x22σ2
    它的方差(二次矩)半径为σ。把这个公式和一维高斯光束光强公式
    I(x)=e-2x2wx2
    比较,就会发现W=2σ。无论是W还是σ,实验上都没办法直接测量。但是如下定义的宽度实验上是可以测量的:用一个刀片,横向扫描过光束,这样一部分光束被刀片遮挡,另外一部分会通过。如果通过的光强等于总光强的90%时刀片坐标为x1,通过的光强等于总光强的10%时刀片坐标为x2,这样光束的宽度可以用
    D=|x2-x1|
    表示。当然,这个比例不局限于10%和90%,也可能是其他值。这种实验方法称为“刀锋(knife edge)法”。这样的话,我们需要找出一个D和W(或者σ)的关系。可惜,这个关系依赖于光束的光强分布,所以不存在一种普遍适用的关系。但是对于TEM00高斯光束,这个关系不难得到。
  3. TEM00高斯光束
  4. 因为刀片在一维方向移动,所以我们只要对光强进行一维积分就可以了。高斯函数的积分为误差函数。例如我们计算宽度D内通过的光强占总光强的比例:
    -D2D2e-2x2w2dx-e-2x2w2dx=erf(2D2w)
    按照上面的例子,这个比值应该是80%。通过查表或者数值计算,我们可以得到
    D=1.2816w=2.5631σ
    这是TEM00高斯光束的结果。对于其他分布种类的光束,这个结果会有变化。
  5. M2因子
  6. 对于TEM00高斯光束来讲,光束半径在光轴方向(z方向)的变化可以表示为
    w2(z)=w02+(λπw0)2(z-z0)2
    其中z0表示TEM00高斯模式腰的位置。对于一般光束,我们已经提到过,光束发散程度一定超过TEM00高斯光束,所以可以引入一个M2因子,这样一般光束半径可以表示为
    w2(z)=w02+M4×(λπw0)2(z-z0)2
    上述各式均是在某单一横向方向(例如x),对于一般光束,x和y方向可能有不同的半径和M2(例如半导体激光),甚至各个方向都不相同,这时候就需要更多方向上的测量才能确定光束分布。M2可以作为光束质量的一个量度。M2越接近1,光束质量越好,发散越小,聚焦时形成的斑点越小。
  7. 刀锋法测量
  8. 上面的例子中,我们用10%和90%作为光束宽度的测量标准,那么可不可以用其他数值呢?另外,上面得到的D和W之间的关系只对于TEM00高斯光束适用,那么一般的光束半径如何测量呢?Siegman的一篇论文阐述了这个问题,结论是对于绝大多数激光光束,如果阈值选择在8.5%到11.6%之间,TEM00高斯光束的结果都可以作为很好的近似,10%无疑是一个很好的折衷。其实对于大多数激光光束而言,TEM00都是主要成分,这样的近似在大多数时候都是没什么问题的。 测量时,可以在不同的位置z多测几组,然后进行拟合,得到光束的M2和其他各个参数。