在线性时间内对两个离散随机变量求和的概率质量

时间:2015-06-05 05:38:37

标签: arrays algorithm complexity-theory probability-density

给定两个离散随机变量,它们(任意)概率质量函数ab以及自然数N,使得两个变量都具有域{{1} (因此函数可以表示为数组),函数的相应随机变量具有给定总和(即[0..N])的概率可以在O(N)时间内通过将数组视为向量来计算并使用他们的点积,虽然其中一个输入被反转,两个输入都被重新切片以便对齐它们并消除边界误差;因此,P(A+B==target)的每个职位i都与a的职位j匹配,以便b。这样的算法看起来像这样:

i+j==target

给定相同的信息,可以将变量的和作为其自己的离散随机变量,尽管其概率质量函数未知。评估该概率质量函数的整体(从而产生与其对应的阵列)可以通过执行N个点积来在O(N 2)时间内完成,每个乘积的操作数被不同地移位;即:

-- same runtime as dotProduct and sum; other components are O(1)
P :: Vector Int -> Vector Int -> Int -> Ratio Int
P a b target | length a /= length b = undefined
             | 0 <= target && target <= 2 * length a
             = (dotProduct (shift target a) (reverse (shift target b))) 
               %
               (sum a * sum b) -- O(length a)
             -- == sum $ map (\x -> (a!x)*(b!(target-x))) [0..length a]
             | otherwise = 0

    where
        -- O(1)
        shift t v = slice start' len' v
            where start = t - length v - 1
                  len = length v - abs start
                  -- unlike `drop ... $ take ... v`,
                  -- slice does not simply `id` when given out-of-bounds indices
                  start' = min (V.length v) (max 0 start)
                  len'   = min (V.length v) (max 0 len)

        -- usual linear-algebra definition
        -- O(length a); length inequality already guarded-away by caller
        dotProduct a b = sum $ zipWith (*) a b
然而,我被告知,产生这种概率质量函数值的表实际上可以在O(N * log(N))时间内完成。据我所知,所有涉及的点积的乘法中没有两个共享相同的有序索引对,我不认为我可以,例如,以任何有用的方式组合两个点子副产品来形成一个pm :: Vector Int -> Vector Int -> Vector (Ratio Int) pm a b = map (P a b) $ generate (2 * length a + 1) id 类型的递归;因此,我很好奇如何以及为什么这样的运行时是可能的。

1 个答案:

答案 0 :(得分:1)

简而言之,你有一个变换F(称为离散傅立叶变换),它将大小为N的矢量集映射到自身上,这样就可以了

F(a*b) = F(a).F(b)

其中*是您刚才描述的卷积运算符,.是标准点积。

此外F是可逆的,因此您可以将a*b恢复为

a*b = F^{-1}(F(a).F(b))

现在这一切都非常好,但关键是F(和F^{-1})可以使用快速傅里叶变换(FFT)在O(N log(N))时间内计算。因此,因为可以在.中计算通常的点积O(N),所以您获得了用于计算两个分布的卷积的O(N log(N))算法。

因此,我建议您查找thisthat