MATLAB中的Map函数?
我有点惊讶MATLAB没有一个映射函数,所以我自己动手做了一个,因为没有它我就活不下去了。有更好的版本吗?有没有一个标准的MATLAB函数编程库是我所缺少的MATLAB中的Map函数?,matlab,functional-programming,map-function,Matlab,Functional Programming,Map Function,我有点惊讶MATLAB没有一个映射函数,所以我自己动手做了一个,因为没有它我就活不下去了。有更好的版本吗?有没有一个标准的MATLAB函数编程库是我所缺少的 函数结果=映射(f,列表) %为什么MATLAB没有映射函数? 结果=零(1,长度(列表)); 对于k=1:长度(列表) 结果(1,k)=f(列表(k)); 结束 结束 用法可能是 map( @(x)x^2,1:10) 如果matlab没有内置的映射函数,可能是出于效率考虑。在您的实现中,您使用循环来迭代列表的元素,这在matlab世界
函数结果=映射(f,列表)
%为什么MATLAB没有映射函数?
结果=零(1,长度(列表));
对于k=1:长度(列表)
结果(1,k)=f(列表(k));
结束
结束
用法可能是
map( @(x)x^2,1:10)
如果matlab没有内置的映射函数,可能是出于效率考虑。在您的实现中,您使用循环来迭代列表的元素,这在matlab世界中通常是不受欢迎的。大多数内置的matlab函数都是“矢量化”的,即。E在整个数组上调用函数比自己迭代并为每个元素调用函数更有效 换句话说,这个
a = 1:10;
a.^2
比这快多了
a = 1:10;
map(@(x)x^2, a)
假设您对map的定义。简短的回答是:内置函数的作用与您的
map
函数对数值数组的作用完全相同:
>> y = arrayfun(@(x) x^2, 1:10)
y =
1 4 9 16 25 36 49 64 81 100
还有另外两个类似的内置函数:(作用于单元数组的元素)和(作用于结构的每个字段)
但是,如果利用矢量化,特别是使用元素化,则通常不需要这些函数。对于您给出的示例,矢量化解决方案应为:
>> x = 1:10;
>> y = x.^2
y =
1 4 9 16 25 36 49 64 81 100
a = [ 10 20 30 40 50 ]; % the array with the original values
b = [ 10 8 6 4 2 ]; % the mapping array
c = zeros( 1, 10 ); % your target array
一些操作将自动跨元素操作(如向向量添加标量值),而另一些操作符具有元素操作的特殊语法(在操作符前面用
表示)。MATLAB中的许多内置函数设计为使用元素操作(通常应用于给定维度,例如和),对向量和矩阵参数进行操作,因此不需要映射函数
总而言之,这里有一些不同的方法来平方数组中的每个元素:
x = 1:10; % Sample array
f = @(x) x.^2; % Anonymous function that squares each element of its input
% Option #1:
y = x.^2; % Use the element-wise power operator
% Option #2:
y = f(x); % Pass a vector to f
% Option #3:
y = arrayfun(f, x); % Pass each element to f separately
当然,对于这样一个简单的操作,选项#1是最明智(也是最有效)的选择。您不需要
map
,因为应用于值列表的标量函数应用于每个值,因此其工作原理与map
类似。试试看
l = 1:10
f = @(x) x + 1
f(l)
在你的特殊情况下,你甚至可以写作
l.^2
除了向量和元素操作外,还有用于在单元数组上映射函数的
cellfun
。例如:
cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans =
'A' 'B' 'C'
如果“UniformOutput”为true(或未提供),它将尝试根据单元格数组的维度连接结果,因此
cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC
使用Matlab的矢量化,一个相当简单的解决方案是:
>> x = 1:10;
>> y = x.^2
y =
1 4 9 16 25 36 49 64 81 100
a = [ 10 20 30 40 50 ]; % the array with the original values
b = [ 10 8 6 4 2 ]; % the mapping array
c = zeros( 1, 10 ); % your target array
现在,打字
c( b ) = a
返回
c = 0 50 0 40 0 30 0 20 0 10
c(b)是对大小为5的向量的引用,其中c的元素在b给出的索引处。现在,如果将值分配到此参考向量,则会覆盖c中的原始值,因为c(b)包含对c中值的引用,而没有副本。如果所需的结果是函数数组,则内置arrayfun似乎不起作用: 如: 地图(@(x)[x^2 x^3],1:10) 下面的轻微修改会使这项工作更好:
function results = map(f,list)
% why doesn't MATLAB have a Map function?
for k = 1:length(list)
if (k==1)
r1=f(list(k));
results = zeros(length(r1),length(list));
results(:,k)=r1;
else
results(:,k) = f(list(k));
end;
end;
end
如前面的答案所述,矢量化解决方案可能是提高速度的最佳解决方案。矢量化也很成熟,感觉很好 有了这些,Matlab现在有了一个Map容器类
参见第1课从其他语言到Matlab:不要使用for循环,它们比矢量化解决方案慢几个数量级。随着JIT的引入,for循环不再像以前那样受到惩罚。@Cookieoff Fault我认为这不再是真的了…@AnderBiguri我认为他们增加了一些改进,但速度仍然慢得多。文件交换有
map
,foldl
(也称为reduce
),select
(又称filter
),以及其他不可或缺的好东西。推荐(如果你必须使用Matlab)。-1:事实上不是这样。Matlab没有足够强的类型系统来指定标量函数。用向量调用f,并在示例中执行单个向量加法。要验证这一点,请对代码示例进行概要分析(“概要文件打开”在运行代码之前,然后是“概要文件关闭报告”)。您将看到有一个对f的调用。我认为他的观点不是他希望它必须循环,而是简单地指定为具有将提供的函数应用于提供的数组的相应元素的结果数组。我对matlab了解不多,但arrayfun似乎完成了这项工作。大多数内置的matlab函数和操作符已经完成了这项工作:它们对输入数组的每个元素进行操作,并返回相应的结果数组。对于您的示例,您只需包含输入参数,'UniformOutput',false)
创建一个包含数组的单元格数组输出,然后格式化并组合成一个非单元格数组。需要注意的是,选项1不仅简单,而且速度更快(与选项3相比,选项2应该与选项1非常相似)!Op讨论的是高阶函数,即,cellfun
等,而不是哈希表或键值对。