swap: Matlab 中交换两个变量

作者: , 共 2385 字 , 共阅读 0

Matlab 程序效率低下,其中一个原因就是它的参数无法引用,每次都是传值。这不但导致效率问题,要实现某些功能,也需要一些特殊的手段。比如最简单的,如果交换两个变量的值,也就是在 C/C++里的函数 void swap(int& a, int& b),在 C/C++里实现很容易,但在 Matlab 里,你会吗?

下面这个解决方法很巧妙,因为它的实现很有参考价值(来源,可以下载.m 版本),附在下面欣赏一下。

function swap(A,B)
% SWAP - swap contents of two variables
%   SWAP(A,B) puts the contents of variable A into variable B and vice versa.
%   You can use either function syntax 'swap(A,B)' or command syntax 'swap A B'.
%
%   Example:
%     A = 1:4 ; B = 'Hello' ;
%     swap(A,B) ;
%     A % -> Hello
%     B % -> 1  2  3  4
%
%     SWAP(A,B) is a convenient easy short-cut for other (series of)
%     commands that have the same effect, e.g.,
%       temp=A ; A=B ; B=temp ; clear temp ;
%       [B,A] = deal(A,B) ;
%     The advantage over these two methods is that using SWAP one does not
%     have to declare intermediate variables or worry about output.
%
%     See also DEAL

% Tested in Matlab R13
% version 1.1 (sep 2006)
% (c) Jos van der Geest
% email: jos@jasen.nl

% 1.1 Use <deal> to swap (insight from Urs Schwarz)
%     Added command syntax functionality (suggested by Duane Hanselman)
%     Modified help section 

error(nargchk(2,2,nargin)) ;

if ischar(A) && ischar(B),
    % command syntax: SWAP VAR1 VAR2
    evalstr = sprintf('[%s,%s] = deal(%s,%s) ;',B,A,A,B) ;
elseif ~isempty(inputname(1)) && ~isempty(inputname(2)),
    % function syntax: SWAP(VAR1,VAR2)
    evalstr = sprintf('[%s,%s] = deal(%s,%s) ;',inputname(2),inputname(1),inputname(1),inputname(2)) ;
else
    % No valid command syntax, force error
    evalstr = '[:)' ;
end
evalin('caller',evalstr,'error(''Requires two (string names of) existing variables'')') ; 

另外附 Matlab 参数传递的方式(来源):

Matlab 使用的是一种叫作"copy-on-write"的矩阵拷贝构造函数,假如你定义了函数

function myfun(A,B)
do something

并在主程序中调用了myfun(Amat,Bmat),此时程序并不是把 Amat/Bmat 的内容全部复制给 A 和 B ,而是新建两个局部变量 A 和 B ,这两个变量的数据部分通过两个指针分别指向 Amat 和 Bmat 数据段进行共享数据,并把 Amat/Bmat 中的一个叫作 refcnt(reference count)的变量加一。这样避免了拷贝大量数据的开销。

在 myfun 中,如果你只读取 A 中的数据,此时,使用 A 完全等价于使用 Amat 中的数据, 但如果你需要修改 A 中的数据,此时 Matlab 先检查 A(Amat)的 refcnt ,如果这个数大于 1,则说明除了 A,还有其他矩阵也同时共享这个数据,为了保证这次修改仅对于 A 有效,这时候 Matlab 才会在内存中复制原来 Amat 的数据内容给 A ,然后修改 A 中的数据。此时 A 已与 Amat 分离。

大多数 C++矩阵类都是通过 refcnt 的机制来进行复制的。

如果有大量参数传递,可以考虑写 c mex/fortran mex ,也可以使用 global ,还可以用evalin(WS,...)

Q. E. D.

类似文章:
本文结论:不要过度担心 Matlab 的传值调用的效率问题。
相似度: 0.074
最近写了一些 Matlab 程序,想起以前想过的一个东西,记录一下。
编程 » Matlab
Matlab 在启动时会自动运行脚本startup.m。在这个脚本里可以自动修改当前目录,修改显示方式等等。比如
上次大规模使用 Matlab 还是本科的时候,当时还是 5.3 版,现在重新尝试它,已经是 7.8 ( R2009a ),而且 R2010b 版都已经发售。而这些版本引入的一个新玩意儿便是面向对象化编程( object-oriented programming , OOP )。
编程 » Bash
BASH 的一些笔记。
相似度: 0.066
编程 » Matlab
写了一个统计代码量的函数,函数已上传到 Matlab Central File Exchange下载地址,使用方法:
最近用 Matlab 写了个东西,运行效率不如我意。用 Profiler 跟踪了一下,结果让我大吃一惊。其中三分之一的时间花费在 datestr 这个函数上,六分之一的时间花费在 save 和 load 数据上。这里先谈前一个问题,关于 save 和 load 的效率以后再谈。
编程 » Matlab, 并行计算
parfor适用于
编程 » C++, C++11
花括号初始化是C++11引入的一种初始化方法。
相似度: 0.058
编程 » Matlab, 代码准则
我所在部门也不是 IT 部门,职位也不是开发职位,但平时工作还是需要大量处理和分析数据、计算和开发各种指标等,还是需要写很多程序,语言以 VBA 和 Matlab。但同时,部门里像着我这种写程序的人并不多,别人并不看我的代码而只关心我提交的结果(说实话,大多数时候即便我写错了也不会有人知道),工作环境也不像专业的 IT 公司或部门,有严格的流程控制和工作平台。我这里没有版本控制、没有自动测试环境、没有代码格式和注释要求,也不需要去 Linux 下干活。我相信国内金融行业有不少人与我处于同样的状态。
题目来源:《A practical Guide to quantitative finance interviews》,解答和书上的可能不一样。
碎碎念 » 学历, 教育
本科学位已经不够用了,证据有两个: