swap: Matlab中交换两个变量

作者:

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
在写 Matlab 程序时,函数的命名方式让人头疼,很难保证刚写的一个函数名在很久以前被用过,成为隐藏的一颗炸弹。
编程 » Matlab
Matlab 在启动时会自动运行脚本 startup.m。在这个脚本里可以自动修改当前目录,修改显示方式等等。比如
编程 » Matlab
第一步, which函数可用来获取 Matlab 函数的全路径(包含路径和文件名)。
编程 » Matlab
读者来信:
编程 » Matlab
写了一个统计代码量的函数,函数已 上传到 Matlab Central File Exchange 下载地址 ,使用方法:
题目来源:《A practical Guide to quantitative finance interviews》,解答和书上的可能不一样。
碎碎念 » 学历, 教育
本科学位已经不够用了,证据有两个: