【问题标题】:Undefined function or variable after strcat in MatlabMatlab中strcat后未定义的函数或变量
【发布时间】:2016-07-17 07:32:15
【问题描述】:

我有一个函数向量,我正在尝试从中获取子集。我将向量中的函数转换为一个元胞数组,以便可以对其进行索引。这是脚本

coeff1 = 1;
coeff2 = 2;
coeff3 = 3;

F = @(x) [... 
coeff1*x(1)*x(4); ...
0; ...
coeff2*x(3); ... 
coeff3*x(7)*x(3) ...
];

G = regexp(func2str(F), ';|\[|\]', 'split');
H = cellfun(@str2func, strcat(G{1}, G(2:end-1)), 'uni', 0);
F2 = @(y)cellfun(@(x)x(y),H(2:4));
F2(rand(1,4));

但是在测试函数时出现错误。它说coeff1 未定义。不知何故,解析的函数无法识别它。有什么问题?

提前致谢。

【问题讨论】:

  • 澄清一下,F 不是函数向量,而是返回向量的函数
  • 那么为什么索引F 的输出还不够呢?
  • @zeeMonkeez 感谢您的更正!索引 F 的输出是不够的。我需要子集,因为我正在测试需要它的算法。
  • 也许你可以解释一下潜在的问题。 regexping 函数字符串并将它们重新组合在一起似乎非常老套且不可靠
  • 此行为在the documentation: Function handles created using str2func do not have access to variables outside of their local workspace or to nested functions. And there is an example 中明确说明。

标签: regex string matlab function string-concatenation


【解决方案1】:

正如@excaza 所指出的,使用str2func 生成的函数无法访问不在其工作区中的变量。这给您留下了两种解决方法:您可以用 strrepregexprep 的值替换变量名称的出现:coeff1 变为 (1) 等。或者您可以将所有系数存储在一个向量中并将它们作为第二个参数:

F = @(x, coeff) [... 
coeff(1)*x(1)*x(4); ...

这仍然让您处理字符串操作和函数句柄操作。两者都很昂贵并且容易损坏。由于您最初的问题略有不同,并且特别提到您想要速度,所以让我建议一种不同的方法:

您的示例表明F 具有特定的结构,即每一行是x 的特定元素乘以一个常数的乘积。 在这种情况下,您可以根据需要利用 this 结构生成函数句柄:

% Coefficient matrix for x. Along second dimension, 
% elements of x will be multiplied with these factors. Along third
% dimension, these products (multiplied with the corresponding item of C)
% will be summed. 

X = logical(cat(3, ...
  [  1     0     0
     0     1     1
     0     0     0
     0     0     0
     1     1     1  ], ...
  [  0     0     0
     1     0     0
     0     0     0
     0     0     1
     0     0     0  ]));

% coefficients for each row
C = [ 1, 2
      2, 3
      0, 0
      0, 3
      1, 0 ];

% anonymous function generating anonymous functions for particular rows
F = @(ind) @(x) sum(C(ind, :) .* squeeze(prod(bsxfun(@times, X(ind, :, :), x) + ~X(ind, :, :), 2)), 2);
% get one of those functions and test
newF = F([2 4]);
x = [1, 2, 3];
newF(x)

allF = F(':');
allF(x)

所以F 是一个函数,给定行索引,返回一个可应用于x 的函数。

【讨论】:

  • 很聪明,但是有一些行的形式为 coeffxx1*x2+coeffyx3*x4。这并不能真正回答问题:s
  • @milez excaza 和我已经列出了为什么您尝试做的事情是不可能的,但有一些警告;这是我现在的答案。我还扩展了示例以反映总和。我仍然打赌这比字符串/单元格/str2func 操作快得多。
  • 是的,效率很高!很高兴知道它不能按照我想象的方式完成。
猜你喜欢
  • 2012-04-15
  • 2013-02-24
  • 2023-03-08
  • 2013-09-27
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
相关资源
最近更新 更多