我看到等效的操作在我的Matlab代码中被做了几次,我认为,必须有一种方法来压缩这些并一次完成。在本例中,它检查的是某些变量是否小于某个ε:
if abs(beta) < tol
beta = 0;
end
if abs(alpha) < tol
alpha = 0;
end
if abs(gamma) < tol
gamma = 0;
end
我试着把这些组合成几行来处理整个文件,
overTol = [alpha,beta,gamma] >= tol;
[alpha,beta,gamma] = [alpha,beta,gamma] .* overTol;
如果这是Python,列表就是列表就是列表,那就没问题了,但在Matlab中,除了特殊情况外,右边的操作会在左边产生一个变量。
阅读完在MATLAB中同时定义多个变量?并宣布&在MATLAB中在一行中初始化变量而不使用数组或向量,我尝试使用deal
,但[alpha,beta,gamma] = deal([alpha,beta,gamma] .* overTol);
不会在左边的向量中的项之间分配给交易函数的向量的项,而是将整个向量的副本提供给每个项。
我想做的最后一件事是让右边等于一个唯一的向量然后让,和等于这个向量的项,一个接一个。这和我刚开始写的一样丑。
是否有一个优雅的解决方案?
好的,评论解释了为什么可能有更好的方法。我很好奇这能不能做到。它可以,但也许不应该。
% Initial values
a = 0.01; b = 0.1; c = 1;
% Tolerance
tol = 0.05;
% Function - note returns a scalar cell
f = @(f) {f.*(abs(f)>tol)}
% arrayfun returns a cell of the new values
% cell2struct turns that into a struct array with a single field 'f'
% the trailing dot-reference extracts that field and builds a
% comma-separated list which can be used to assign the new values
[a2,b2,c2] = cell2struct(arrayfun(f, [a,b,c]),{'f'}).f
您可以使用cellfun
生成结果的单元数组,并使用deal
将其重新分配回变量
f = @(x) x.*(abs(x)>tol); % function which returns x, or x if abs(x)<tol
d = cellfun( f, {a,b,c}, 'uni', 0 ); % apply function to inputs a,b,c
[a,b,c] = deal(d{:}); % deal results back to a,b,c
一个更具可读性(和维护友好)的方法可能是只使用函数,并接受它将使用更多行。行数不是敌人…
a = applyTol(a);
b = applyTol(b);
c = applyTol(c);
function x = applyTol( x )
tol = 0.5;
if abs(x) < tol
x = 0;
end
end