当我在Matlab中执行一个函数时。有时我有方程式,其中每一个都有常数。然后,我必须在我的函数中声明这些常量。我想知道是否有办法从函数外部调用该常量的值,如果我在工作区中有它们的值。
我不想在函数声明中将此值写为函数的输入。
答案 0 :(得分:4)
除了Iterator提供的解决方案之外,我认为你还有其他一些选择。
首先,我想警告你关于全局变量(正如Iterator所做的那样):这些引入了隐藏的依赖关系,使得重用和调试代码变得更加麻烦。如果您在调用函数时唯一关心的是易用性,我建议您传递包含这些常量的结构。这样做的好处是可以轻松地将这些常量保存在一起。除非你知道自己在做什么,否则请帮自己一个忙,远离全局变量(以及eval
,evalin
和assignin
等函数。)
在global
,evalin
旁边并传递结构,还有另一种全局状态机制:首选项。当它涉及几乎不可变的代码设置时,将使用它们。这些不适合传递实际原始数据。
如果你想要的只是一个或多或少干净的语法来调用某个函数,这可以通过几种不同的方式来实现:
您可以使用可变数量的参数。当常量具有默认值时,这是最佳选项。我将通过一个例子解释,例如常规正弦波y = A*sin(2*pi*t/T)
(A
是幅度,T
周期)。在MATLAB中,可以将其实现为:
function y = sinewave(t,A,T)
y = A*sin(2*pi*t/T);
调用此函数时,我们需要提供所有参数。如果我们将此函数扩展为类似以下内容,我们可以省略A
和T
参数:
function y = sinewave(t,A,T)
if nargin < 3
T = 1; % default period is 1
if nargin < 2
A = 1; % default amplitude 1
end
end
y = A*sin(2*pi*t/T);
这使用了构造nargin
,如果你想了解更多,那么值得查阅nargin
,varargin
,varargout
和{{1}的MATLAB帮助}}。但是,请注意,当您要提供nargout
的值时,必须为A
提供值。有一种更方便的方法来获得更好的行为:
T
这样做的好处是更清楚发生了什么,你可以省略function y = sinewave(t,A,T)
if ~exists('T','var') || isempty(T)
T = 1; % default period is 1
end
if ~exists('A','var') || isempty(A)
A = 1; % default amplitude 1
end
y = A*sin(2*pi*t/T);
但仍然指定A
(前一个例子可以做同样的事情,但是当这个问题变得很复杂时你有很多参数)。您可以通过调用T
来执行此类操作,其中sinewave(1:10,[],4)
将保留其默认值。如果空输入有效,则应使用另一个无效输入(例如A
,NaN
或已知为正的参数的负值,...)。
使用上述功能,以下所有呼叫都是等效的:
inf
如果参数没有默认值,您可以将函数包装到一个填充这些参数的函数句柄中。当您使用某些工具箱时,可能需要执行此操作,这些工具箱会对要使用的函数施加约束。优化工具箱就是这种情况。
我将再次考虑t = rand(1,10);
y1 = sinewave(t,1,1);
y2 = sinewave(t,1);
y3 = sinewave(t);
函数,但这次我使用第一个定义(即没有可变数量的参数)。然后你可以使用函数句柄:
sinewave
您可以像使用其他功能一样使用f:
e.g。 f = @(x)(sinewave(x,1,1));
将评估f(10)
。
通过这种方式,您可以编写一个通用函数(即尽可能通用且简单的sinewave(10,1,1)
),但您可以动态创建一个函数(句柄),并替换常量。这允许您使用该功能,但也可以防止数据的全局存储。
您当然可以结合不同的解决方案:例如使用可变数量的参数创建函数句柄来设置某个全局变量。
答案 1 :(得分:3)
解决这个问题的最简单方法是通过全局变量: http://www.mathworks.com/help/techdoc/ref/global.html
您还可以在其他工作空间中获取值,包括基本工作空间或父工作空间,但这是不明智的,因为您不一定知道包装给定函数的内容。
如果你想走这条路,请看看evalin
功能:
http://www.mathworks.com/help/techdoc/ref/evalin.html
但是,标准方法是传递您需要的所有变量。如果愿意,您可以将它们放入结构中,并且只传递一个结构。