在Matlab中使用strcat之后未定义的函数或变量 [英] Undefined function or variable after strcat in Matlab

查看:2183
本文介绍了在Matlab中使用strcat之后未定义的函数或变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数向量,我试图从中获取子集。我将矢量中的函数转换为单元格数组,以便我可以将其编入索引。这是脚本

  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 未定义。不知何故解析函数不能识别它。什么可能是错的?



提前致谢。

@excaza指出,使用 str2func 生成的函数不能访问不在其工作空间中的变量。这给您带来了两种解决方法:您可以用 strrep regexprep :<$替换变量名称的出现次数c $ c> coeff1 变成(1)等等。或者你可以将所有系数存储在一个向量中,并将它们作为第二个参数传递: / p>

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

这仍然让您处理字符串操作和函数句柄操作。两者都是昂贵的并且容易打破。由于您的原始问题稍有不同,并且特别提到您需要速度,请让我建议一种不同的方法:您的示例显示 F $ b

/ code>具有特定的结构,即每行是 x 的特定元素的乘积,乘以一个常数。
在这种情况下,你可以利用这个结构在你需要的时候生成函数句柄:

 %系数矩阵为x。沿着第二维,x的
%元素将乘以这些因素。沿着第三个
%维度,这些产品(乘以相应的C项)
%将被累加。

X =逻辑(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]));

每行的系数
C = [1,2
2,3
0,0
0,3
1, 0];

匿名函数为特定行生成匿名函数
F = @(ind)@(x)sum(C(ind,:)。* squeeze(prod(bsxfun(@times, X(ind,:,:),x)+〜X(ind,:,:),2)),2);
%获得这些函数之一并测试
newF = F([2 4]);
x = [1,2,3];
newF(x)

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

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


I have a vector of functions and I am trying to obtain subsets from it. I transform the functions in the vector into a cell array so that I can index into it. Here is the script

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));

But I get an error when testing the function. It says coeff1 is undefined. Somehow the parsed function does not recognize it. What could be wrong?

Thanks in advance.

解决方案

As @excaza has noted, functions generated with str2func do not have access to variables not in their workspace. That leaves you with two workarounds: you could replace occurrences of variable names with the value with strrep or regexprep: coeff1 becomes (1), etc. Or you could store all coefficients in one vector and pass them as a second argument:

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

That still leaves you to deal with string operations and function handle operations. Both are costly and prone to breaking. Since your original question is slightly different, and specifically mentions that you want speed, let me suggest a different approach:

Your example suggests that F has a particular structure, namely that each line is the product of particular elements of x, multiplied by a constant. In that case, you can utilize the this structure to generate function handles as you need them:

% 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)

So F is the function that, given row indices, returns a function that can be applied to x.

这篇关于在Matlab中使用strcat之后未定义的函数或变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆