【问题标题】:Matlab - dynamically produce string for anonymous functionMatlab - 为匿名函数动态生成字符串
【发布时间】:2015-05-14 20:35:47
【问题描述】:

我正在尝试根据输入参数的数量为匿名函数生成参数字符串而不使用 for 循环。例如,如果 N=3,那么我想要一个这样的字符串

@(ax(1),ax(2),ax(3),ay(1),ay(2),ay(3))

我尝试使用 repmat('ax',1,N) 但我不知道如何交错 (i) 索引。

有什么想法吗?


除此之外:到目前为止,答案很好,上述问题已经解决。为了给那些想知道为什么的人提供一些直觉,我想这样做:我需要构造一个大小为 3000x3000 的非常大的矩阵匿名函数(雅可比行列式)。我最初使用Matlab操作jacobian和matlabFunction来构造匿名函数;但是,这很慢。相反,由于导数的封闭形式非常简单,我决定直接形成匿名函数。这是通过形成符号雅可比矩阵 J,然后使用 char(J{:})' 将其附加到上述 @() 字符串并使用 eval 来形成最终的匿名函数来完成的。这可能不是最优雅的解决方案,但我发现它比 jacobian/matlabFunction 组合运行得快得多,尤其是对于大 N(此外,新方法的结构允许并行进行评估)。

编辑:为了完整起见,匿名函数的参数字符串的正确形式应该是

@(ax1,ax2,ax3,ay1,ay2,ay3)

避免与索引相关的语法错误。

【问题讨论】:

  • 使用字符串来做到这一点不是一个很好的解决方案。我怀疑您可能想改用varargin。您想准确构建哪些匿名函数?其次:您在那里创建的语法在 MATLAB 中无效。
  • 期待我的 Mentalist 徽章,我预测 OP 真的想要这样的东西:f = @(ax, ay) ...,然后将通过 f([a,b,c],[d,e,f]) 调用
  • 感谢您尝试澄清。我仍然不明白答案如何解决您的问题。如果您在它们上使用str2func,它们只会产生语法错误。
  • 本着从符号导数构建快速函数的精神,我建议使用来自this answer 的概念。它可以生成漂亮的代码,并且速度就像您手动构建函数一样快。
  • @knedlsepp 谢谢!我会调查的。

标签: string matlab


【解决方案1】:

试试这个:

N = 3;
sx = strcat('ax(', arrayfun(@num2str, 1:N, 'uniformoutput', 0), '),');
sy = strcat('ay(', arrayfun(@num2str, 1:N, 'uniformoutput', 0), '),');
str = [sx{:} sy{:}];
str = ['@(' str(1:end-1) ')']

【讨论】:

  • 太好了,谢谢!请问第二组方括号在str定义中的作用是什么?
  • 再次感谢您的回答,但我发现当 N>9 时这会产生不正确的输出。
  • @Erik 不需要这些括号。我已经更正了,现在它也适用于 N>9
【解决方案2】:

解决方案是使用arrayfun:

sx = strjoin(arrayfun(@(x) ['ax(' num2str(x) ')'], 1:3, 'UniformOutput', false), ',');
sy = strjoin(arrayfun(@(x) ['ay(' num2str(x) ')'], 1:3, 'UniformOutput', false), ',');
s = ['@(' sx ',' sy ')'];

包含

'@(ax(1),ax(2),ax(3),ay(1),ay(2),ay(3))'

最好的,

【讨论】:

  • 您好,谢谢!不幸的是,我的 Matlab 版本中没有 strjoin。这是最近添加的功能吗?有什么方法可以使用其他功能复制它?
  • 哦,是的,我认为它出现在 R2014b 中。我正在使用 R2015a。您在 Matlab Central 上有此 equivalent,或者您可以使用 sprintf,如 here 所述。
【解决方案3】:

我建议如下:

N = 3;
argumentString = [repmat('ax(%i),',1,N),repmat('ay(%i),',1,N)];

functionString = sprintf(['@(',argumentString(1:end-1),')'], 1:N, 1:N)

首先,您为 sprintf 创建输入掩码(例如 'ax(%i)'),然后用适当的数字填充该掩码以创建函数字符串。

注意:@(ax(1),...) 语法实际上不起作用。更有可能的是,您想使用 @()someFunction(ax(1),...),或者您尝试将多个输入参数传递给现有函数,在这种情况下,将输入存储在一个元胞数组中并以 fun(axCell{:}) 的形式调用该函数。

【讨论】:

  • 我没有得到所有的答案。 OP 想要的东西没有任何意义!?
  • 您好,谢谢。是的,我打算将函数(以字符串形式)附加到上面,然后使用 eval() 来获取我的匿名函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-09
相关资源
最近更新 更多