Vector julia中的3向量和n向量的广播向量乘法

Vector julia中的3向量和n向量的广播向量乘法,vector,julia,linear-algebra,Vector,Julia,Linear Algebra,我有一个3-向量c=[0.7,0.5,0.2],我想把它与n-向量x=rand(-1,1),n中的一切相乘,这样我得到一个结果n+2-向量y,其中y[I]==x[I]*c[3]+x[I-1]*c[2]+x[I-2]*c[1] 朱莉娅,我该怎么做?我觉得应该有办法将较小的3向量传播到n向量中的所有值。对于边缘情况,如果i-1或i-2超出边界,我只希望这些组件为零。这里有一种方法可以使用 创建带有初始零的滞后版本的x: x = 1:5 xminus1 = lag(x, 1, default=0) x

我有一个3-向量
c=[0.7,0.5,0.2]
,我想把它与n-向量
x=rand(-1,1),n
中的一切相乘,这样我得到一个结果n+2-向量y,其中
y[I]==x[I]*c[3]+x[I-1]*c[2]+x[I-2]*c[1]


朱莉娅,我该怎么做?我觉得应该有办法将较小的3向量传播到n向量中的所有值。对于边缘情况,如果i-1或i-2超出边界,我只希望这些组件为零。

这里有一种方法可以使用

创建带有初始零的滞后版本的
x

x = 1:5
xminus1 = lag(x, 1, default=0)
xminus2 = lag(x, 2, default=0)
水平连接向量并使用矩阵乘法与
c

X = [xminus2 xminus1 x]
X * c
以下是REPL中的
X
X*c
的外观:

julia>X=[xminus2 xminus1 X]
5×3数组{Int64,2}:
0  0  1
0  1  2
1  2  3
2  3  4
3  4  5
朱莉娅>X*c
五元素数组{Float64,1}:
0.2
0.9
2.3
3.7
5.1

请注意,这将生成长度
length(x)
,而不是
length(x)+2
的输出向量。我不确定输出的长度为
length(x)+2是否有意义,正如您在问题中所要求的那样。

如果我正确理解您的问题,您需要卷积,在标准卷积中,向量
c
会反转。为此,您可以使用例如DSP.jl

这是你想要的吗

julia> using DSP

julia> c = [0.7, 0.5, 0.2]
3-element Array{Float64,1}:
 0.7
 0.5
 0.2

julia> conv([10, 100, 1000, 10000], reverse(c))
6-element Array{Float64,1}:
    1.9999999999996967
   25.0
  257.0000000000003
 2569.9999999999995
 5700.0
 6999.999999999998
您也可以使用
linearagebra
模块中的
dot
手动实现它,如下所示:

julia> using LinearAlgebra

julia> x = [10, 100, 1000, 10000]
4-element Array{Int64,1}:
    10
   100
  1000
 10000

julia> y = [0;0;x;0;0]
8-element Array{Int64,1}:
     0
     0
    10
   100
  1000
 10000
     0
     0

julia> [dot(@view(y[i:i+2]), c) for i in 1:length(x)+2]
6-element Array{Float64,1}:
    2.0
   25.0
  257.0
 2570.0
 5700.0
 7000.0
julia> c = [0.7, 0.5, 0.2]; # from question

julia> x = [10, 100, 1000, 10_000]; # from another answer

julia> using Tullio, OffsetArrays

julia> @tullio y[i] := x[i]*c[3] + x[i-1]*c[2] + x[i-2]*c[1]
2-element OffsetArray(::Vector{Float64}, 3:4) with eltype Float64 with indices 3:4:
  257.0
 2570.0

julia> @tullio y[i] := x[i+k-3] * c[k] # sum over all k, range of i that's safe
2-element OffsetArray(::Array{Float64,1}, 3:4) with eltype Float64 with indices 3:4:
  257.0
 2570.0

我有一套做这种事的方法。最简单的用法如下:

julia> using LinearAlgebra

julia> x = [10, 100, 1000, 10000]
4-element Array{Int64,1}:
    10
   100
  1000
 10000

julia> y = [0;0;x;0;0]
8-element Array{Int64,1}:
     0
     0
    10
   100
  1000
 10000
     0
     0

julia> [dot(@view(y[i:i+2]), c) for i in 1:length(x)+2]
6-element Array{Float64,1}:
    2.0
   25.0
  257.0
 2570.0
 5700.0
 7000.0
julia> c = [0.7, 0.5, 0.2]; # from question

julia> x = [10, 100, 1000, 10_000]; # from another answer

julia> using Tullio, OffsetArrays

julia> @tullio y[i] := x[i]*c[3] + x[i-1]*c[2] + x[i-2]*c[1]
2-element OffsetArray(::Vector{Float64}, 3:4) with eltype Float64 with indices 3:4:
  257.0
 2570.0

julia> @tullio y[i] := x[i+k-3] * c[k] # sum over all k, range of i that's safe
2-element OffsetArray(::Array{Float64,1}, 3:4) with eltype Float64 with indices 3:4:
  257.0
 2570.0
由于
eachindex(c)==1:3
,这就是它求和的
k
-值的范围,
i
的范围尽可能大,因此
i+k-3
保持在
eachindex(x)==1:4的范围内

要通过在每个方向上用两个零填充
x
来扩展
i
的范围,请写入
pad(i+k-3,2)
。要计算生成一个普通的基于1的数组所需的
i
的偏移量,请在左侧写入
i+
(然后
-3
没有任何区别)。然后:


在较大的阵列上,这不会很快(目前),因为它必须在每一步检查它是在
x
内还是在填充中。很可能
DSP.conv
在这方面更聪明一些。(编辑--DSP.jl对于这个
c
,似乎从来没有更快过;对于长度为1000的内核,对于
x
中的10^6个元素,它更快过)

看起来像是DPS.jl函数可以
xcorr(x,c;padmode=:longest)
,而不需要反转。的确,但似乎应该使用
padmode=:none