有人可以向我解释@(函数句柄)运算符的含义以及使用它的原因吗?
我之前只使用过MATLAB 6.5.我有一些使用'@'的程序.有人能告诉我它是什么吗?
那么,MATLAB 6.5是否支持这种运算符?
MATLAB允许为自定义类重载各种运算符.其中一个未列出的可重载运算符end,可以从\matlab\lang\end.m以下方面了解到:
% END(A,K,N) is called for indexing expressions involving the object A
% when END is part of the K-th index out of N indices. For example,
% the expression A(end-1,:) calls A's END method with END(A,1,2).
Run Code Online (Sandbox Code Playgroud)
这种方法的一个例子是table.end(粘贴在MATLAB命令行中并按"打开选择"以转到其定义;它在中定义...\matlab\datatypes\@tabular\end.m).
与普通方法不同,人们不能简单地写hEnd = @end,因为这会给出错误:
>> hEnd = @end;
hEnd = @end;
?
Error: Illegal use of reserved keyword "end".
Run Code Online (Sandbox Code Playgroud)
另一方面,写入e = str2func('end');工作,但它链接到默认end功能(即使临时切换到end.m找到所需的文件夹).
失败的尝试包括str2func('table>end');, …
从事涉及遗传算法的任务(头痛负荷,有趣的负担).我需要能够测试不同的交叉方法和不同的基因突变的方法,来比较其结果(本文我必须写在课程的一部分).因此,我想将函数名称作为函数句柄传递给Repopulate方法.
function newpop = Repopulate(population, crossOverMethod, mutationMethod)
...
child = crossOverMethod(parent1, parent2, @mutationMethod);
...
function child = crossOverMethod(parent1, parent2, mutationMethod)
...
if (mutateThisChild == true)
child = mutationMethod(child);
end
...
Run Code Online (Sandbox Code Playgroud)
这里的关键点是3,参数3:如何将mutationMethod传递到另一个级别?如果我使用@符号,我会被告知:
"mutationMethod" was previously used as a variable,
conflicting with its use here as the name of a function or command.
Run Code Online (Sandbox Code Playgroud)
如果我不使用@符号,那么在没有参数的情况下调用mutationMethod,并且非常不满意.
虽然我知道是的,但我可以重写我的代码以使其工作方式不同,我现在很好奇如何让它实际工作.
任何帮助是极大的赞赏.
如果我inline在MATLAB中使用该函数,我可以创建一个单独的函数名称,可以根据以前的选择做出不同的响应:
if (someCondition)
p = inline('a - b','a','b');
else
p = inline('a + b','a','b');
end
c = p(1,2);
d = p(3,4);
Run Code Online (Sandbox Code Playgroud)
但是我正在创建的内联函数变得非常史诗,所以我想将它们更改为其他类型的函数(即m文件,子函数或嵌套函数).
假设我有m个文件,比如Mercator.m,KavrayskiyVII.m等等(都取值phi和lambda),我想以p与上面相同的方式分配所选择的函数,以便我可以调用它多次(带可变大小的矩阵和使用eval不可能或完全混乱的东西.
我有一个变量,type,那将是所需要的功能(例如该名称中的一个'Mercator','KavrayskiyVII'等等).我想我需要p进入一个指向type变量内部命名函数的指针.我有什么想法可以做到这一点?
假设我有一个foo定义为的函数
[a b] = foo(c ).
Run Code Online (Sandbox Code Playgroud)
如果我考虑一个函数句柄
f = @(c)foo(c)
Run Code Online (Sandbox Code Playgroud)
例如,在一个cellfun电话中使用,我得到的是一个f等同于foo定义的行为
a = foo(c)
Run Code Online (Sandbox Code Playgroud)
即,返回的值b丢失.
因此,当这样的一个f被cellfun调用时,输出单元将只有as并且将错过bs(我当前关心的).目视
cellfun(f,input)
[a(input{1})] ?
[a(input{2})] ?
.... b gets killed along the way
Run Code Online (Sandbox Code Playgroud)
问:如何定义一个函数句柄foo其捕获只是bS' 即赋予类似的定义行为foo像
b = foo(c)
Run Code Online (Sandbox Code Playgroud)
即^ 2,浪费了 a秒.
此外,是否可以(有效地)捕获两者a并b在一个独特的 cellfun呼叫中?
问题:在Matlab中,如何检查函数句柄是特定函数还是函数类型?
例如:我们f1是一个函数句柄.如何检查是否f1是内置的Matlab函数mean?如何检查是否f1是匿名函数?
我目前的解决方案:我目前解决此问题的方法是调用该functions函数.functions接受一个函数句柄作为输入,并返回一个包含输入函数句柄信息的结构,例如函数类型,路径,函数名等.它可以工作,但它不是一个理想的解决方案,因为,引用官方文档:
"注意事项MATLAB®仅提供functions用于查询和调试的功能.由于其行为可能会在后续版本中发生变化,因此您不应将其用于编程目的."
我开始用C++实现一些m文件,以减少运行时间.m文件产生n维点并在这些点评估函数值.这些函数是用户定义的,它们作为函数句柄传递给m文件和mex文件.mex文件使用mexCallMATLAB和feval来查找函数值.
我构造了下面的例子,其中在Matlab命令行中构造的函数句柄fn被传递给matlabcallingmatlab.m和mexcallingmatlab.cpp例程.使用新开放的Matlab,mexcallingmatlab在241.5秒内评估此功能200000,而matlabcallingmatlab在0.81522秒内评估它,因此使用mex实现减慢296倍.这些时间是第二次运行的结果,因为第一次运行似乎更大可能是由于第一次加载程序等相关的一些开销.
我花了很多天在网上搜索这个问题并尝试了一些建议.我尝试了不同的mex编译标志来优化mex,但性能几乎没有差异.Stackoverflow上的一篇文章指出,升级Matlab是解决方案,但我在Mac OS X版本:10.8.4上使用的最新版本MATLAB版本:8.1.0.604(R2013a).我使用和不使用-largeArrayDims标志编译了mex文件,但这也没有任何区别.有人建议函数句柄的内容可以直接在cpp文件中编码,但这是不可能的,因为我想将此代码提供给具有矢量输入和实数输出的任何类型函数的任何用户.
据我所知,mex文件需要通过feval函数来使用函数句柄,而m文件可以直接调用函数句柄,前提是Matlab版本比某些版本更新.
任何帮助将不胜感激.
在Matlab命令行中创建的简单函数句柄:
fn = @(x) x'*x
Run Code Online (Sandbox Code Playgroud)
matlabcallingmatlab.m:
function matlabcallingmatlab( fn )
x = zeros(2,1);
for i = 0 : 199999
x(2) = i;
f = fn( x );
end
Run Code Online (Sandbox Code Playgroud)
mexcallingmatlab.cpp:
#include "mex.h"
#include <cstring>
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
mxArray *lhs[1], *rhs[2]; //parameters to be passed to feval
double f, *xptr, x[] = {0.0, 0.0}; // x: input to f and f=f(x)
int …Run Code Online (Sandbox Code Playgroud) 我有一个缓存评估功能.作为参数之一,它需要一个函数句柄.在某些情况下,函数句柄是不可访问的,我不太明白为什么.下面的例子显示了让我难过的原因:
>> A.a = @plus; feval(@A.a, 1, 1)
ans =
2
>> clear A
>> A.a.a = @plus; feval(@A.a.a, 1, 1)
Error using feval
Undefined function 'A.a.a' for input arguments of type 'double'.
Run Code Online (Sandbox Code Playgroud)
因此,如果我将一个函数句柄存储为一个结构成员,如果它是一个深度,我可以传递它,但如果它是两个级别深,则不能.在我的实际使用情况下,我有一个结构D保存各种类别的许多(117)的情况下,所以其实我有stct.obj.meth,这里stct是一个结构,obj是一个类的实例/对象,meth是一种方法.传递@stct.obj.meth失败,但如果我分配A = stct.obj,则传递@A.meth成功.
在什么条件下我可以将函数句柄作为参数传递,以便它仍然可以在堆栈中访问?
编辑:虽然在上面的用例中,我可以简单地删除@因为@plus已经是一个函数句柄.但是,请考虑以下情况:
>> type cltest.m
classdef cltest < handle
methods
function C = mymeth(self, a, b)
C = a + b;
end
end …Run Code Online (Sandbox Code Playgroud) 是否有可能将function_handle的衍生物作为另一个function_handle?
喜欢:
fun1 = @(x) x^2;
% do that ...
disp(fun2);
@(x) x*2
Run Code Online (Sandbox Code Playgroud)
我知道如何找到符号函数的导数但我无法将function_handle转换为符号函数.
我是matlab的新手,我找不到任何办法.提前致谢.
function-handle ×10
matlab ×10
c++ ×1
derivative ×1
function ×1
matlab-class ×1
mex ×1
namespaces ×1
oop ×1
operators ×1
performance ×1
stack ×1
string ×1
symbols ×1
syntax ×1