Category Archives: Techniques

Tail Recursions

http://www.cs.sfu.ca/CC/310/pwfong/Lisp/2/tutorial2.html

Recursive functions are usually easier to reason about. Notice how we articulate the correctness of recursive functions in this and the previous tutorial. However, some naive programmers complain that recursive functions are slow when compared to their iterative counter parts. For example, consider the original implementation of factorial we saw in the previous tutorial:

(defun factorial (N)
  "Compute the factorial of N."
  (if (= N 1)
      1
    (* N (factorial (- N 1)))))

It is fair to point out that, as recursion unfolds, stack frames will have to be set up, function arguments will have to be pushed into the stack, so on and so forth, resulting in unnecessary runtime overhead not experienced by the iterative counterpart of the above factorial function:

int factorial(int N) {
  int A = 1;
  while (N != 1) {
    A = A * N;
    N = N - 1;
  }
  return A;
}

Because of this and other excuses, programmers conclude that they could write off recursive implementations …

Modern compilers for functional programming languages usually implement tail-recursive call optimizations which automatically translate a certain kind of linear recursion into efficient iterations. A linear recursive function is tail-recursive if the result of each recursive call is returned right away as the value of the function. Let’s examine the implementation of fast-factorial again:

(defun fast-factorial (N)
  "A tail-recursive version of factorial."
  (fast-factorial-aux N 1))

(defun fast-factorial-aux (N A)
  "Multiply A by the factorial of N."
  (if (= N 1)
      A
    (fast-factorial-aux (- N 1) (* N A))))

Notice that, in fast-factorial-aux, there is no work left to be done after the recursive call (fast-factorial-aux (- N 1) (* N A)). Consequently, the compiler will not create new stack frame or push arguments, but instead simply bind (- N 1) to N and (* N A) to A, and jump to the beginning of the function. Such optimization effectively renders fast-factorial as efficient as its iterative counterpart. Notice also the striking structural similarity between the two.

When you implement linearly recursive functions, you are encouraged to restructure it as a tail recursion after you have fully debugged your implementation. Doing so allows the compiler to optimize away stack management code. However, you should do so only after you get the prototype function correctly implemented. Notice that the technique of accumulator variables can be used even when we are not transforming code to tail recursions. For some problems, the use of accumulator variables offers the most natural solutions.

OpenCV Matrix指针的玄妙

假设定义一个Matrix:
CvMat* uv = cvCreateMat(16, 2, CV_32FC1);
float* temp = (float*)(uv->data.ptr + 8);

第一种情况:
float* temp1 = (float*)(uv->data.ptr + 8 + 4 * 2);

第二种情况:
float* temp2 = temp + 8;

我第一反应是这两种情况是一样的,而且第二种方法可以节约计算时间,因为少一次乘法,而且我也是这么做的,而且特意写成了第2种写法。

但事实上,temp1只是在temp这个指针的基础上加8个字节,而temp2是在temp的基础上加8 * sizeof(float) = 32字节,中间差了很多。这就是一下午debug的收获。

Linear least squares

http://en.wikipedia.org/wiki/Linear_least_squares

Limitations
The least squares approach relies on the calculation of the pseudo inverse (A^T\! A)^{-1} A^T. The pseudo inverse is guaranteed to exist for any full-rank matrix A. However, in some cases the matrix ATA is ill-conditioned; this occurs when the measurements are only marginally related to the estimated parameters. In these cases, the least squares estimate amplifies the measurement noise, and may be grossly inaccurate. This may occur even when the pseudo inverse itself can be accurately calculated numerically. Various regularization techniques can be applied in such cases, the most common of which is called Tikhonov regularization. If further information about the parameters is known, for example, a range of possible values of x, then minimax techniques can also be used to increase the stability of the solution.

Another drawback of the least squares estimator is the fact that it seeks to minimize the norm of the measurement error, Axb. In many cases, one is truly interested in obtaining small error in the parameter x, e.g., a small value of \|\mathbf{x}-\hat{\mathbf{x}}\|. However, since x is unknown, this quantity cannot be directly minimized. If a prior probability on x is known, then a Bayes estimator can be used to minimize the mean squared error, E \left\{ \| \mathbf{x} - \hat{\mathbf{x}} \|^2 \right\}. The least squares method is often applied when no prior is known. Surprisingly, however, better estimators can be constructed, an effect known as Stein’s phenomenon. For example, if the measurement error is Gaussian, several estimators are known which dominate, or outperform, the least squares technique; the most common of these is the James-Stein estimator.

Nonlinear Least Squares Fitting
http://mathworld.wolfram.com/NonlinearLeastSquaresFitting.html
http://statpages.org/nonlin.html
http://www.itl.nist.gov/div898/strd/general/bkground.html

Recommendations for taking calibration photos

Written by Alexander Velizhev

http://research.graphicon.ru/calibration/recommendations-for-taking-calibration-photos.html

Attention! Verify your calibration pattern size. If you have entered wrong object dimentions detection will run incorrectly. It runs only with calibration patterns using odd x even (or even x odd) number of squares (i.e 5×6, 7×8, 10×7, etc).

Recommendations
  • The white space (marked with red on the picture below) between the outer squares and the object boundary should be at least 1 square wide, like this:

    Image

    Figure 1. Calibration pattern

  • All the squares must be clearly visible (unoccluded).

  • Use a tripod

  • Take 25 images and more

  • Use a paper size ".3" and more

  • Square size is 3-5 cm

  • The chessboard on the images must be located in the all places of the camera matrix 

    Image

    Figure 2. Point density

  • The chessboard must be plane

  • Take photos from these positions + from the top of the chessboard

    Image

    Figure 3. Camera positions

  • The tilt angle is constant (for example 45 deg)

    Image

    Figure 4. Tilt angle

  • Take photos with three camera positions

    Image

    Figure 5. Tilts of the camera

Another thing is that I actually tested only on my images, so maybe my modifications won’t help other people to do their calibration. If so – send me your image sequences, I’ll try to tune up my method to work with them also.

Camera Calibration Tutorial

马上要写Camera Calibration的hw了,先储备着,做IBVH也用的着。
http://kwon3d.com/theory/calib.html, 这个网页是系统介绍Motion Analysis的一部分,初步看看写的还不错。
Flexible New Technique for Camera Calibration
Robust Multi-camera Calibration (calibration for light field cameras)
Multi-Camera Self-Calibration
Camera Calibration Toolbox for Matlab

Optimize code

列举一些用在IBVH里的优化策略:

1. 用 for (i = n-1; i >= 0; –i) 不用 for (i = 0; i < n; i++) 与0比较的效率高,–i的效率比i–的效率高;check http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.15 可以知道为什么++i 比 i++ 更有效率;

2. 使用Int,因为计算机目前大多是32位的;

3. 将local functions声明成static, e.g.,
           static void fun()
这样别的cpp文件里的函数就没法调用该函数了,一些编译器会优化这点;

4.  对c++来说使用 ‘op=’ ,比如,使用
           myClass += value;
不用
           myClass = myClass + value;
第2种情况会产生一个temporary object;

5. 尽量使用inline函数,如果不在意生成的可执行程序的大小

6. 尽量去掉for loop,尽管这样会增加代码量;如果不行,可以尽量使用while语句来替代for语句;

7. 使用“引用”不是“指针”,即:
           int x; 
           void Ptr(const int* p) { x += *p; }
           void Ref(const int& p) { x += p; }        // good
使用reference的好处在于:
           a. There’s no need to check that the reference is not NULL. References are never NULL. (Creating a NULL reference is possible, but difficult). 
           b. References don’t require the * dereference operator. Less typing. Cleaner code.
           c. There’s the opportunity for greater efficiency with references. A major challenge for compiler writers is producing high-performance code with pointers. Pointers make it extremely difficult for a compiler to know when different variables refer to the same location, which prevents the compiler from generating the fastest possible code. Since a variable reference points to the same location during its entire life, a C++ compiler can do a better job of optimization than it can with pointer-based code. There’s no guarantee that your compiler will do a better job at optimization, but it might.

————–

还有一些常用的优化策略:

1. 将发生概率大的case放到switch语句的前面;

Using vi with Lisp

Most Lisp developers prefer emacs to vi since emacs allows one to run Lisp within a separate buffer with a tightly integrated compile/test cycle. For those already familiar with vi, vi can do two of the most important functions you would need from the editor:

  • balance the parentheses.
    set sm turns on the blinking of matching parens as you type the close parenthesis.
    Typing % when the cursor is on a parenthesis will move the cursor to the matching parenthesis.
  • indent expressions.
    vi allows to set different modes, either by setting them in your .cshrc file in the EXINIT variable (as shown later) or by setting them once you are in vi using the command :set . The modes you are interested in are:
    • set ai turns on auto-indentation. This means that each line you type will match the previous line’s indentation.
    • set lisp turns on lisp mode. This means the indenting is done as required by Lisp.

    You can set the desired modes to vi by adding this line to your .cshrc file:

    setenv EXINIT 'map # Ji^M^[|set wm=6 para=lpppipnpbp sect=shuh showmatch ai'

    or by defining in your .cshrc file an alias command for vi (in the example shown here is li ) that includes all the modes you want when using lisp:

    alias li "vi '+set ic lisp ai wm=0 |map # Ji^M^[ |1' \!*"

    You can also set the modes after you are in vi by typing :set ai lisp

When using Xwindows, the easiest solution is to have two xterm windows, one for Lisp and one for vi. Do not forget to reload your file into Lisp every time you change it.

Lisp tutorial

对Lisp没什么好感,但是为了做AI的作业,还是要看一下的。昨天搜了一下,发现没有什么写的比较好的tutorial,文档比起Python来说,网上的资源实在是很差。虽然AI的老师说作业可以用Python来做,虽然我对Python很感兴趣,但还是怕花的时间比直接学Lisp的时间还长。忍了,去看看Lisp吧,看看Lisp到底有多好,一个老美居然认为学会Lisp是他上AI的主要收获之一。

谢谢Sophie同学给的一些链接:

Learning Lisp
Common LISP Hints
Common Lisp: A Brief Tutorial
Programming in Emacs Lisp – An introduction
Paul Graham’s Lisp Page

Sorting in C++ vs. C

There is a tradeoff between writing special-case code yourself, calling a special-case library routine, and calling a general-case library routine. I would like to have:

  • Speed: Naturally, I want my program to run as fast as possible. General-case library code usually does not give me speed, because it’s not optimized for my particular situation. I’d be better off using special-case code. Hand-written code is usually (but not always) best here, because it can take advantage of specialized knowledge of the data.
  • Flexibility: I want to have code that works in many different situations. Special-case library code does not give me flexibility, because it’s only written for certain situations. I’d be better off using a general-case library routine or my own code (which I can copy and modify in new situations) for flexibility. A general-case library is best because I don’t have to copy and paste (a maintenance nightmare).
  • Ease of Coding: I want to write as little as possible to get the job done. Writing code myself does not satisfy this goal. I’d be better off using a library routine. Special-case library routines are best because I don’t have to specify as many parameters.

As you can see, none of the solutions gives me all three. Given any one goal, there is a corresponding best solution. Given any one solution, I can only get two out of three goals. In this document I present a comparison of sorting in C and C++, and show that with C++ STL, you can get all three.

Appendix: Running Times

Data
Type

C
(library)

C
(hand-coded)

Numerical
Recipes

Ratio
1

C++
(C array)

C++
(vector class)

Ratio
2

int

5.90-5.92

1.54-1.65

1.46-1.50

3.7

1.12-1.16

1.11-1.14

5.3

short

9.03-9.03

1.73-1.80

1.58-1.59*

5.1

1.17-1.20

1.17-1.19

7.7

byte

7.87-7.89

0.98-1.02

0.98-1.00

7.9

0.70-0.73

0.70-0.73

11.0

float

7.08-7.10

2.38-2.50

2.48-2.55

2.9

1.96-2.02

1.97-2.02

3.6

double

16.42-16.45

2.70-2.93

2.72-2.83

5.8

2.28-2.35

2.28-2.37

7.1

by Amit Patel

http://theory.stanford.edu/~amitp/rants/c++-vs-c/

Programming Tutorials

http://www.cprogramming.com/tutorial.html