面向科研的编程技巧 Research Oriented Programming Skills

本文长期更新,汇总一些自己在平时科研中逐渐领悟到的一些编程技巧,欢迎交流,欢迎指导。文中的内容基本会结合自己遇到的具体例子来说明。
科研与做产品不同,在写代码的过程中往往要经过很多调试,修改参数,调整数据结构等,因此便于调试是面向科研编程的第一要义。

General:

关于 Git 的使用

我现在还没有很熟练的应用 Git 中的分支和版本回退等功能,主要还是当作一个代码托管和多终端查看的地方。其实在写代码的过程中,频繁地 commit 是个好习惯。但注意,从远程的 repository 拉取代码到本地覆盖之前还是要想清楚。另外个人觉得,本地的仓库可以经常更新,但推送到远程仓库去的最好还是取得阶段成果的版本。另外注意保持写说明的好习惯。

关于代码复用

在编写代码中经常出现这样的情况,给 A 项目写了个函数(文件),结果 B 项目中也会用到。一个办法是把原来的函数或者文件复制一份到新的项目中去。但这样就有一个问题,随着后续的调试,本来功能相同或相似的代码会生长成两个不同的版本,这样在后面需要合并的时候往往又会耗费大量的时间和精力。因此,比较好的方法就是在需要调用别处代码的时候直接将别处的代码的引用指向新的项目。
比如,在MATLAB中,可以用 addpath() 将另一个函数所在的路径添加到当前的程序中。
另外,在 VS 和 MATLAB 联合调试中,可以结合宏的使用共同调试一份源代码。

关于 solver 的接口

在仿真中需要对多个 solver 进行比较时,最好分别用 wrapper 函数分别将这几个 solver (不管是自己写的还是调用现成的)写成统一的接口,这样在仿真时便于输入,也便于对输出进行比较。
比如,在比较几个 QP 求解器的速度和迭代次数时,将几个 solver 的输入都写成自己通用的标准 QP 命题中参数,同时将迭代次数和求解时间在 wrapper 函数中进行提取和计算,作为接口的标准输出,这样在外层调用 solver 的函数时更加方便整齐。

For C Code:

关于宏的使用

刚开始接触 C 时是不大会用宏的,但逐渐了解并走了很多弯路后才认识到宏的价值。一个在代码中会经常访问和修改的参数,我们可以用一个变量来表示。那么代码中经常使用和修改的语句(命令)就可以用宏来表示。
比如,我的一个 C 代码在初步调试后要用 MEX 文件连接在 MATLAB 中进行调试。在 VS 中调试时,我可以用 printf() 来打印变量值;而在 MATLAB 中调试时,打印函数要用 mexPrintf() 。如果不用宏,我可能要手动修改源代码中的所有 printf() 。那如果我采用宏定义:

#define Print mexPrintf     // For Matlab debug
//#define Print printf      // For Visual Studio debug

那么即使我切换使用 VS 和 MATLAB 进行调试,也能很容易地修改源代码中的打印函数。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章