为什么 cumsum 不使用符号向量?
Why is cumsum not working with symbolic vectors?
我在符号向量上写了一个涉及 cumsum
的小 Octave 脚本,我希望它能工作,但不幸的是,它没有。
这是代码:
pkg load symbolic
n = 3;
syms q x
q = sym('q', [n 1]);
x = sym('x', [n 1]);
cumsum(q - x)
我得到的不是预期的结果:
error: cumsum: wrong type argument 'class'
为什么会这样?它可以与 Matlab Symbolic Toolbox 一起使用吗? (不幸的是,我没有它,所以我无法测试。)
这只是因为如错误消息所示,符号元素不支持用 Octave 编写的 cumsum
。您的代码在 MATLAB 中给出以下内容:
ans =
q1 - x1
q1 + q2 - x1 - x2
q1 + q2 + q3 - x1 - x2 - x3
你可以这样做:
t1 = q-x;
t2 = triu(ones(numel(t1)));
sum(repmat(t1,1,3).*t2).'
% repmat is necessary here because implicit expansion is also not
% supported for matrices of class sym in Octave
以上Octave和MATLAB中的代码分别给出如下:
ans = (sym 3×1 matrix)
⎡ q₁₁ - x₁₁ ⎤
⎢ ⎥
⎢ q₁₁ + q₂₁ - x₁₁ - x₂₁ ⎥
⎢ ⎥
⎣q₁₁ + q₂₁ + q₃₁ - x₁₁ - x₂₁ - x₃₁⎦
ans =
q1 - x1
q1 + q2 - x1 - x2
q1 + q2 + q3 - x1 - x2 - x3
冒着陈述显而易见的风险,这可以作为 for 循环来实现。
这是一种实现方式。
function Y = cumsum( X, N )
if nargin < 2, N = 1; end
YDims = size( X ); NDim = YDims(N); Y = sym( zeros( YDims ) );
XIdx = substruct( '()', repmat( {':'}, 1, ndims( X ) ) );
YIdx = substruct( '()', repmat( {':'}, 1, ndims( Y ) ) );
for i = 1 : NDim
XIdx.subs{N} = 1 : i;
YIdx.subs{N} = i;
Y = subsasgn( Y,
YIdx,
sum( subsref( X, XIdx ), N )
);
end
end
将此复制到您的符号安装文件夹1 as cumsum.m 并且您的上述脚本将像在 matlab 中一样工作。
1:(在我的例子中是 ~/.octave/symbolic-2.9.0/@sym/cumsum.m 因为我已经将我的 pkg 前缀设置为 ~/.octave )
我在符号向量上写了一个涉及 cumsum
的小 Octave 脚本,我希望它能工作,但不幸的是,它没有。
这是代码:
pkg load symbolic
n = 3;
syms q x
q = sym('q', [n 1]);
x = sym('x', [n 1]);
cumsum(q - x)
我得到的不是预期的结果:
error: cumsum: wrong type argument 'class'
为什么会这样?它可以与 Matlab Symbolic Toolbox 一起使用吗? (不幸的是,我没有它,所以我无法测试。)
这只是因为如错误消息所示,符号元素不支持用 Octave 编写的 cumsum
。您的代码在 MATLAB 中给出以下内容:
ans =
q1 - x1
q1 + q2 - x1 - x2
q1 + q2 + q3 - x1 - x2 - x3
你可以这样做:
t1 = q-x;
t2 = triu(ones(numel(t1)));
sum(repmat(t1,1,3).*t2).'
% repmat is necessary here because implicit expansion is also not
% supported for matrices of class sym in Octave
以上Octave和MATLAB中的代码分别给出如下:
ans = (sym 3×1 matrix)
⎡ q₁₁ - x₁₁ ⎤
⎢ ⎥
⎢ q₁₁ + q₂₁ - x₁₁ - x₂₁ ⎥
⎢ ⎥
⎣q₁₁ + q₂₁ + q₃₁ - x₁₁ - x₂₁ - x₃₁⎦
ans =
q1 - x1
q1 + q2 - x1 - x2
q1 + q2 + q3 - x1 - x2 - x3
冒着陈述显而易见的风险,这可以作为 for 循环来实现。
这是一种实现方式。
function Y = cumsum( X, N )
if nargin < 2, N = 1; end
YDims = size( X ); NDim = YDims(N); Y = sym( zeros( YDims ) );
XIdx = substruct( '()', repmat( {':'}, 1, ndims( X ) ) );
YIdx = substruct( '()', repmat( {':'}, 1, ndims( Y ) ) );
for i = 1 : NDim
XIdx.subs{N} = 1 : i;
YIdx.subs{N} = i;
Y = subsasgn( Y,
YIdx,
sum( subsref( X, XIdx ), N )
);
end
end
将此复制到您的符号安装文件夹1 as cumsum.m 并且您的上述脚本将像在 matlab 中一样工作。
1:(在我的例子中是 ~/.octave/symbolic-2.9.0/@sym/cumsum.m 因为我已经将我的 pkg 前缀设置为 ~/.octave )