- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
编辑 2:这篇文章似乎已经从 CrossValidated 转移到 StackOverflow,因为它主要是关于编程的,但这意味着花哨的 MathJax 不再起作用了。希望这仍然是可读的。
假设我想用协方差矩阵 S
计算两个向量 x
和 y
之间的平方马氏距离。这是一个由
M2(x, y; S) = (x - y)^T * S^-1 * (x - y)
使用 python 的 numpy
包我可以这样做
# x, y = numpy.ndarray of shape (n,)
# s_inv = numpy.ndarray of shape (n, n)
diff = x - y
d2 = diff.T.dot(s_inv).dot(diff)
或在 R 中作为
diff <- x - y
d2 <- t(diff) %*% s_inv %*% diff
不过,就我而言,我得到了
m
by n
矩阵 X
n
维向量mu
n
by n
协方差矩阵S
并且想要找到 m
维向量 d
使得
d_i = M2(x_i, mu; S) ( i = 1 .. m )
其中 x_i
是 X
的第 i
行。
这在 python 中使用一个简单的循环并不难:
d = numpy.zeros((m,))
for i in range(m):
diff = x[i,:] - mu
d[i] = diff.T.dot(s_inv).dot(diff)
当然,考虑到外循环是在 python 中而不是在 numpy
库中的 native 代码中发生的,这意味着它没有达到预期的速度。 $n$ 和 $m$ 分别约为 3-4 和几十万,我在交互式程序中经常这样做,因此加速将非常有用。
从数学上讲,我能够使用基本矩阵运算来表达这一点的唯一方法是
d = diag( X' * S^-1 * X'^T )
在哪里
x'_i = x_i - mu
写一个矢量化版本很简单,但不幸的是,计算一个超过 100 亿的元素矩阵并且只取对角线的效率低下...我相信这个操作应该很容易用爱因斯坦符号表达,因此有望使用 numpy
的 einsum
函数进行快速评估,但我什至还没有开始弄清楚这个黑魔法是如何工作的。
所以,我想知道:有没有更好的方法来数学地表达这个操作(就简单的矩阵操作而言),或者有人可以建议一些很好的矢量化(python 或 R)代码来有效地做到这一点?
我实际上不想做一次,我想做 k
~ 100 次。鉴于:
m
由 n
矩阵 X
k
由 n
矩阵U
由 n
个协方差矩阵组成的 n
集,每个表示为 S_j
(j = 1..k
)
通过 k
矩阵 D
找到 m
使得
D_i,j = M(x_i, u_j; S_j)
其中i = 1..m
,j = 1..k
,x_i
是i
X
和 u_j
的第 j
行是 U
的第 j
行。
即向量化以下代码:
# s_inv is (k x n x n) array containing "stacked" inverses
# of covariance matrices
d = numpy.zeros( (m, k) )
for j in range(k):
for i in range(m):
diff = x[i, :] - u[j, :]
d[i, j] = diff.T.dot(s_inv[j, :, :]).dot(diff)
最佳答案
首先,您似乎得到了 S 然后将其取反。你不应该那样做;它很慢而且数字不准确。相反,您应该获得 S 的 Cholesky 因子 L,以便 S = L L^T;然后
M^2(x, y; L L^T)
= (x - y)^T (L L^T)^-1 (x - y)
= (x - y)^T L^-T L^-1 (x - y)
= || L^-1 (x - y) ||^2,
并且由于 L 是三角形 L^-1 (x - y) 可以高效计算。
事实证明,如果您适本地 reshape scipy.linalg.solve_triangular
,它会很高兴地同时执行这些操作:
L = np.linalg.cholesky(S)
y = scipy.linalg.solve_triangular(L, (X - mu[np.newaxis]).T, lower=True)
d = np.einsum('ij,ij->j', y, y)
稍微分解一下,y[i, j]
是 L^-1 (X_j -\mu) 的第 i 个分量。然后 einsum
调用会执行
d_j = \sum_i y_{ij} y_{ij}
= \sum_i y_{ij}^2
= || y_j ||^2,
就像我们需要的那样。
不幸的是,solve_triangular
不会对其第一个参数进行矢量化,因此您可能应该只在此处循环。如果 k 仅为 100 左右,那不会是一个重大问题。
如果你实际上得到的是 S^-1 而不是 S,那么你确实可以更直接地使用 einsum
来做到这一点。由于 S 在您的情况下很小,因此实际反转矩阵然后执行此操作也可能会更快。但是,一旦 n 不是平凡的大小,这样做就会损失很多数值精度。
要弄清楚如何使用 einsum,请根据组件编写所有内容。我将直接进入奖金案例,为了符号方便,写 S_j^-1 = T_j:
D_{ij} = M^2(x_i, u_j; S_j)
= (x_i - u_j)^T T_j (x_i - u_j)
= \sum_k (x_i - u_j)_k ( T_j (x_i - u_j) )_k
= \sum_k (x_i - u_j)_k \sum_l (T_j)_{k l} (x_i - u_j)_l
= \sum_{k l} (X_{i k} - U_{j k}) (T_j)_{k l} (X_{i l} - U_{j l})
因此,如果我们制作形状为 (m, n)
的数组 X
,形状为 (k, n) 的
, 和形状为U
(k, n, n)
的T
,那么我们可以把它写成
diff = X[np.newaxis, :, :] - U[:, np.newaxis, :]
D = np.einsum('jik,jkl,jil->ij', diff, T, diff)
其中 diff[j, i, k] = X_[i, k] - U[j, k]
。
关于r - 用于计算(平方)马氏距离的矢量化代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31807843/
SQL 和一般开发的新手,我有一个表(COUNTRIES),其中包含字段(INDEX、NAME、POPULATION、AREA) 通常我添加一个客户端(Delphi)计算字段(DENSITY)和 On
我想使用 calc(100%-100px),但在我的 demo 中不起作用由于高度只接受像素,因此如何将此百分比值转换为像素。 最佳答案 以下将为您提供高度: $(window).height();
我正在尝试在 MySQL 中添加列并动态填充其他列。 例如我有一张表“数字”并具有第 1 列、第 2 列、第 3 列,这些总数应填充在第 4 列中 最佳答案 除非我误解了你的问题,否则你不只是在寻找:
我想返回简单计算的结果,但我不确定如何执行此操作。我的表格如下: SELECT COUNT(fb.engineer_id) AS `total_feedback`, SUM(fb.ra
我一直在尝试做这个程序,但我被卡住了,我仍然是一个初学者,任何帮助将不胜感激。我需要程序来做 打印一个 10 X 10 的表格,其中表格中的每个条目都是行号和列号的总和 包含一个累加器,用于计算所有表
这个计算背后一定有一些逻辑。但我无法得到它。普通数学不会导致这种行为。谁能帮我解释一下原因 printf ("float %f\n", 2/7 * 100.0); 结果打印 1.000000 为什么会
我想计算从 0 到 (n)^{1/2} - 1 的数字的 AND每个数字从 0 到 (n)^{1/2} - 1 .我想在 O(n) 中执行此操作时间,不能使用 XOR、OR、AND 运算。 具体来说,
如何在 Excel 中将公式放入自定义数字格式?例如(出于说明目的随机示例), 假设我有以下数据: 输入 输出 在不编辑单元格中的实际数据的情况下,我想显示单元格中的值除以 2,并保留两位小数: 有没
每次我在 Flutter 应用程序中调用计算()时,我都会看到内存泄漏,据我所知,这基本上只是一种生成隔离的便捷方法。我的应用程序内存占用增加并且在 GC 之后永远不会减少。 我已将我的代码简化为仅调
我有数字特征观察 V1通过 V12用于目标变量 Wavelength .我想计算 Vx 之间的 RMSE列。数据格式如下。 每个变量“Vx”以 5 分钟的间隔进行测量。我想计算所有 Vx 变量的观测值
我正在寻找一种使用 C 语言计算文件中未知字符数的简单方法。谢谢你的帮助 最佳答案 POSIX 方式(可能是您想要的方式): off_t get_file_length( FILE *file ) {
我正在使用 Postgres,并且我正试图围绕如何在连续日期跨度中得出第一个开始日期的问题进行思考。例如 :- ID | Start Date | End Date =================
我有一个订单表格,我在其中使用 jQuery 计算插件来汇总总数。 此求和工作正常,但生成的“总和”存在问题。总之,我希望用逗号替换任何点。 代码的基础是; function ($this) {
我在使用 double 变量计算简单算术方程时遇到问题。 我有一个具有 double 属性 Value 的组件,我将此属性设置为 100。 然后我做一个简单的减法来检查这个值是否真的是 100: va
我在这里看到了一些关于 CRC 32 计算的其他问题。但没有一个让我满意,因此是这样。 openssl 库是否有任何用于计算 CRC32 的 api 支持?我已经在为 SHA1 使用 openssl,
当我在PHP日期计算中遇到问题时,我感到惊讶。 $add = '- 30 days'; echo date('Y-m-01', strtotime($add)); // result is 2017-
我正在使用 javascript 进行练习,我编写了这个脚本来计算 2 个变量的总和,然后在第三个方程中使用这个总和!关于如何完成这项工作的任何想法都将非常有用! First Number:
我有一个来自EAC的提示单和一个包含完整专辑的FLAC文件。 我正在尝试制作一些python脚本来播放文件,因为我需要能够设置在flac文件中开始的位置。 如何从CueSheet格式MM:SS:FF转
这个问题已经有答案了: Adding two numbers concatenates them instead of calculating the sum (24 个回答) 已关闭去年。 我有一个
4000 我需要上面字段 name="quantity" 和 id="price" 中的值,并使用 javascript 函数进行计算,并将其显示在字段 id= 中仅当我单击计算按钮时才显示“总
我是一名优秀的程序员,十分优秀!