【问题标题】:Why is cumsum not working with symbolic vectors?为什么 cumsum 不适用于符号向量?
【发布时间】:2020-10-30 08:30:08
【问题描述】:

我在符号向量上编写了一个涉及cumsum 的小型 Octave 脚本,我希望它可以工作,但不幸的是,它没有。 代码如下:

pkg load symbolic
n = 3;
syms q x
q = sym('q', [n 1]);
x = sym('x', [n 1]);
cumsum(q - x)

我得到的不是预期的结果:

错误:cumsum:错误类型参数“类”

为什么会这样?它可以与 Matlab 符号工具箱一起使用吗? (不幸的是,我没有它,所以我无法测试。)

【问题讨论】:

  • 这在 MATLAB 中使用符号工具箱工作,如您所愿输出 [q1 - x1; q1 + q2 - x1 - x2; q1 + q2 + q3 - x1 - x2 - x3]
  • 与 MATLAB Online 一起使用。所以,我想,它也适用于 MATLAB。
  • 感谢您提出这个问题。我在 [项目页面] (sourceforge.net/p/octave/symbolic/merge-requests) 上添加了基本的 cumsum 和 cumprod 函数作为合并请求。

标签: octave symbolic-math cumsum


【解决方案1】:

这只是因为错误消息所指示的符号元素不支持用 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

【讨论】:

  • 不错的答案。不过,我想知道,在符号数学方面,将 cumsum 实现为 for 循环是否一定比将其作为矩阵计算执行慢得多?
  • 同样有效的是:for i = 1:n; b(i) = sum(q(1:i)) - sum(x(1:i)); end 或更短:A = tril(ones(n)); A*(q - x) 实际上,我已经将tril 版本作为矩阵乘法,但后来我发现(数字)@ 中有错误987654329@ 变体并更正了它。后来,我还想更正左侧矩阵A,以便两个变体给出相同的结果。现在他们做到了。 :)
【解决方案2】:

冒着明显的风险,这可以作为一个 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 为 cumsum.m,您的上述脚本将像在 matlab 中一样工作。


1:(在我的情况下,这是 ~/.octave/symbolic-2.9.0/@sym/cumsum.m 因为我已将我的 pkg 前缀设置为 ~/.octave )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-30
    • 2017-03-14
    • 2014-10-01
    • 1970-01-01
    • 2021-11-17
    • 2018-03-01
    • 1970-01-01
    • 2012-12-23
    相关资源
    最近更新 更多