- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
非常简单的问题:给定一个 N x N 对称矩阵 A 和一个 N 向量 x,是否有内置的 Matlab 函数来计算 x'*A*x
?即,不是 y = x'*A*x
,是否有函数 quadraticform
s.t. y = quadraticform(A, x)
?
显然我可以做 y = x'*A*x
,但我需要性能,似乎应该有一种方法可以利用
A
是对称的如果没有一个内置函数,是否有比 x'*A*x
更快的方法?或者,Matlab 解析器是否足够智能以优化 x'*A*x
?如果是这样,您能否指出文档中可以验证事实的位置?
最佳答案
我找不到这样的内置函数,我知道为什么。
y=x'*A*x
可以写成 n^2
项 A(i,j)*x(i) 的总和*x(j)
,其中 i
和 j
从 1
运行到 n
(其中 A
是一个 nxn
矩阵)。 A
是对称的:A(i,j) = A(j,i)
对于所有 i
和 j
.由于对称性,除 i
等于 j
的项外,每个项在总和中出现两次。所以我们有 n*(n+1)/2
个不同的项。每个都有两个浮点乘法,所以一个朴素的方法总共需要 n*(n+1)
次乘法。很容易看出x'*A*x
的朴素计算,即先计算z=A*x
再计算y=x'* z
,也需要 n*(n+1)
乘法。然而,有一种更快的方法来对我们的 n*(n+1)/2
不同的项求和:对于每个 i
,我们可以分解出 x(i )
,这意味着只有n*(n-1)/2+3*n
次乘法就足够了。但这并没有真正帮助:计算 y=x'*A*x
的运行时间仍然是 O(n^2)
。
所以,我认为二次型的计算不能比 O(n^2)
更快,因为这也可以通过公式 y=x'* 来实现A*x
,特殊的“二次函数”没有真正的优势。
===更新===
我用 C 编写了函数“quadraticform”,作为 Matlab 的扩展:
// y = quadraticform(A, x)
#include "mex.h"
/* Input Arguments */
#define A_in prhs[0]
#define x_in prhs[1]
/* Output Arguments */
#define y_out plhs[0]
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize mA, nA, n, mx, nx;
double *A, *x;
double z, y;
int i, j, k;
if (nrhs != 2) {
mexErrMsgTxt("Two input arguments required.");
} else if (nlhs > 1) {
mexErrMsgTxt("Too many output arguments.");
}
mA = mxGetM(A_in);
nA = mxGetN(A_in);
if (mA != nA)
mexErrMsgTxt("The first input argument must be a quadratic matrix.");
n = mA;
mx = mxGetM(x_in);
nx = mxGetN(x_in);
if (mx != n || nx != 1)
mexErrMsgTxt("The second input argument must be a column vector of proper size.");
A = mxGetPr(A_in);
x = mxGetPr(x_in);
y = 0.0;
k = 0;
for (i = 0; i < n; ++i)
{
z = 0.0;
for (j = 0; j < i; ++j)
z += A[k + j] * x[j];
z *= x[i];
y += A[k + i] * x[i] * x[i] + z + z;
k += n;
}
y_out = mxCreateDoubleScalar(y);
}
我将这段代码保存为“quadraticform.c”,并用 Matlab 编译它:
mex -O quadraticform.c
我写了一个简单的性能测试来比较这个函数与 x'Ax:
clear all; close all; clc;
sizes = int32(logspace(2, 3, 25));
nsizes = length(sizes);
etimes = zeros(nsizes, 2); % Matlab vs. C
nrepeats = 100;
h = waitbar(0, 'Please wait...');
for i = 1 : nrepeats
for j = 1 : nsizes
n = sizes(j);
A = randn(n);
A = (A + A') / 2;
x = randn(n, 1);
if randn > 0
start = tic;
y1 = x' * A * x;
etimes(j, 1) = etimes(j, 1) + toc(start);
start = tic;
y2 = quadraticform(A, x);
etimes(j, 2) = etimes(j, 2) + toc(start);
else
start = tic;
y2 = quadraticform(A, x);
etimes(j, 2) = etimes(j, 2) + toc(start);
start = tic;
y1 = x' * A * x;
etimes(j, 1) = etimes(j, 1) + toc(start);
end;
if abs((y1 - y2) / y2) > 1e-10
error('"x'' * A * x" is not equal to "quadraticform(A, x)"');
end;
waitbar(((i - 1) * nsizes + j) / (nrepeats * nsizes), h);
end;
end;
close(h);
clear A x y;
etimes = etimes / nrepeats;
n = double(sizes);
n2 = n .^ 2.0;
i = nsizes - 2 : nsizes;
n2_1 = mean(etimes(i, 1)) * n2 / mean(n2(i));
n2_2 = mean(etimes(i, 2)) * n2 / mean(n2(i));
figure;
loglog(n, etimes(:, 1), 'r.-', 'LineSmoothing', 'on');
hold on;
loglog(n, etimes(:, 2), 'g.-', 'LineSmoothing', 'on');
loglog(n, n2_1, 'k-', 'LineSmoothing', 'on');
loglog(n, n2_2, 'k-', 'LineSmoothing', 'on');
axis([n(1) n(end) 1e-4 1e-2]);
xlabel('Matrix size, n');
ylabel('Running time (a.u.)');
legend('x'' * A * x', 'quadraticform(A, x)', 'O(n^2)', 'Location', 'NorthWest');
W = 16 / 2.54; H = 12 / 2.54; dpi = 100;
set(gcf, 'PaperPosition', [0, 0, W, H]);
set(gcf, 'PaperSize', [W, H]);
print(gcf, sprintf('-r%d',dpi), '-dpng', 'quadraticformtest.png');
结果很有趣。 x'*A*x
和 quadraticform(A,x)
的运行时间都收敛到 O(n^2)
,但是前者有一个较小的因素:
关于performance - 是否有内置的 matlab 可以计算二次形式 (x'*A*x)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8369832/
我试图在 (C) Python 源代码中找到内置 in 运算符的实现。我在内置函数源代码中搜索过,bltinmodule.c ,但找不到此运算符的实现。我在哪里可以找到这个实现? 我的目标是通过扩展此
我们正在开发一个 shell(学校项目)。我们不理解一种行为。为什么内置函数在重定向时不起作用? 喜欢 cd - | command 不改变目录。 或 export NAME=VALUE | comm
有人问有关如何对列表进行排序的问题。从基本List.Sort()到List.OrderBy()有几种方法。最可笑的是自己动手的SelectionSort。我迅速将其否决,但这使我思考。应用于列表的
我正在尝试使用 C 中内置的 qsort 函数对结构进行排序 typedef struct abc{ long long int fir; long long int sec; }abc; 在
我觉得有一些内置的东西。如果对象为空,我想要默认值(或者特别是 0,我只使用十进制/整数)。是否有编写此函数的内置方法? static int GetDecimalFromObject(object
Java 是否有用于生成和解析文档的内置 XML 库?如果不是,我应该使用哪个第三方? 最佳答案 Sun Java 运行时附带 Xerces 和 Xalan 实现,它们提供解析 XML(通过 DOM
我对 python 的“all”和生成器有以下问题: G = (a for a in [0,1]) all(list(G)) # returns False - as I expected 但是:
我有一些使用 gcc 内部函数的代码。我想包含代码以防缺少内在函数。我该怎么做? #ifdef __builtin_ctzll 不起作用。 最佳答案 使用最新版本的 clang,现在可以使用 __ha
人们常说应该在本地重新声明(某些)Lua 函数,因为这样可以减少开销。但这背后的确切规则/原则是什么?我怎么知道哪些功能应该完成,哪些是多余的?还是应该为每个功能完成,甚至是您自己的功能? 不幸的是,
我想实现以下功能: TestClass values 接受任意数量的 NewClass 对象 只有 NewClass 对象没有完全相同的属性值被添加到TestClass.values 我想出了这个:
我正在尝试编写一个存储过程(使用 SQL Server Management Studio 2008 R2)以从表中检索最大测量值。这似乎是一件容易的事,所以我写了一个简短的存储过程来获取 MAX。但
我刚写了我的第一个Electron应用程序。现在,我正在尝试通过electron-packager构建它。我的package.json看起来像这样: { "name": "pixelcast",
我正在寻找在 WPF 应用程序中使用的“安全”字体系列列表 - 应该安装在所有能够运行 WPF 的客户端机器上的字体系列。 Silverlight 有一个明确定义的列表( listed on MSDN
好吧,(在写了几次之后)发现System.Windows.Controls命名空间中已经有一个BooleanToVisibilityConverter,这真是一个惊喜。 可能还有更多这样隐藏的节省时间
在我的 gradle 构建文件中,我有以下插件 block plugins { `java-library` jacoco checkstyle } 这些都没有指定版本,但一切
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 3 年前。 Improve this ques
10 implementations String#reverse 已根据每个浏览器进行分析。 自 2011 年以来已对这些实现进行了解释。 当 ES6 出现时,有很多代码变得更加优雅和性能。 关于
在 Julia 包 BenchmarkTools 中,有一些像 @btime、@belapse 这样的宏对我来说似乎是多余的,因为 Julia 内置了@time、@elapse 宏。在我看来,这些宏服
我正在尝试编写一个简单的 LLVM 通行证,其目标如下: 查找所有 call指示。 在被调用函数中插入我编写的外部函数。 例如,考虑我有以下示例程序: #include #include int
我理解 'a) -> (rhs:'a -> 'a) -> 'a 在我感兴趣的情况下,我经常发现自己想要类似 (lhs:'a -> 'b) -> (rhs:'c -> 'b) -> 'b 的东西在侧面
我是一名优秀的程序员,十分优秀!