MATLAB:测试匿名向量是否是R^n的子集
作为一名程序员,我试图使用MatLab代码作为学习数学的一种方式 所以我在读这篇关于子空间的文章,并试图构建一些简单的matlab函数来为我做到这一点 以下是我取得的成绩:MATLAB:测试匿名向量是否是R^n的子集,matlab,math,vector,Matlab,Math,Vector,作为一名程序员,我试图使用MatLab代码作为学习数学的一种方式 所以我在读这篇关于子空间的文章,并试图构建一些简单的matlab函数来为我做到这一点 以下是我取得的成绩: function performSubspaceTest(subset, numArgs) % Just a quick and dirty function to perform subspace test on a vector(subset) % % INPUT % subset is the anony
function performSubspaceTest(subset, numArgs)
% Just a quick and dirty function to perform subspace test on a vector(subset)
%
% INPUT
% subset is the anonymous function that defines the vector
% numArgs is the the number of argument that subset takes
% Author: Lasse Nørfeldt (Norfeldt)
% Date: 2012-05-30
% License: http://creativecommons.org/licenses/by-sa/3.0/
if numArgs == 1
subspaceTest = @(subset) single(rref(subset(rand)+subset(rand))) ...
== single(rref(rand*subset(rand)));
elseif numArgs == 2
subspaceTest = @(subset) single(rref(subset(rand,rand)+subset(rand,rand))) ...
== single(rref(rand*subset(rand,rand)));
end
% rand just gives a random number. Converting to single avoids round off
% errors.
% Know that the code can crash if numArgs isn't given or bigger than 2.
outcome = subspaceTest(subset);
if outcome == true
display(['subset IS a subspace of R^' num2str(size(outcome,2))])
else
display(['subset is NOT a subspace of R^' num2str(size(outcome,2))])
end
这些是我正在测试的子集
%% Checking for subspaces
V = @(x) [x, 3*x]
performSubspaceTest(V, 1)
A = @(x) [x, 3*x+1]
performSubspaceTest(A, 1)
B = @(x) [x, x^2, x^3]
performSubspaceTest(B, 1)
C = @(x1, x3) [x1, 0, x3, -5*x1]
performSubspaceTest(C, 2)
运行代码给了我这个
V =
@(x)[x,3*x]
subset IS a subspace of R^2
A =
@(x)[x,3*x+1]
subset is NOT a subspace of R^2
B =
@(x)[x,x^2,x^3]
subset is NOT a subspace of R^3
C =
@(x1,x3)[x1,0,x3,-5*x1]
subset is NOT a subspace of R^4
C不工作(仅当它只接受一个参数时才工作)。
我知道我的numArgs解决方案不是最优的——但这是我目前能够想到的
是否有任何方法可以优化此代码,使C能够正常工作,并可能避免超过2个参数的elseif语句
PS:我似乎找不到一个内置的matlab函数来为我解决这个问题。这里有一种方法。它测试给定函数是否表示线性子空间。从技术上讲,这只是一个概率测试,但失败的可能性微乎其微 首先,我们定义一个很好的抽象。此高阶函数将函数作为其第一个参数,并将该函数应用于矩阵
x
的每一行。这允许我们同时测试func
的多个参数
function y = apply(func,x)
for k = 1:size(x,1)
y(k,:) = func(x(k,:));
end
现在我们编写核心函数。这里的func
是一个参数的函数(假定为R^m
中的向量),它在R^n
中返回向量。我们将func
应用于R^m
中的100个随机选择向量,以获得输出矩阵。如果func
表示一个线性子空间,则输出的值将小于或等于m
function result = isSubspace(func,m)
inputs = rand(100,m);
outputs = apply(func,inputs);
result = rank(outputs) <= m;
非最优的解决方案几乎触及了问题的表面 我认为你一下子做的太多了:
rref
不应该被使用,这会让一切变得复杂。尤其是numArgs
大于1
仔细想想:[1 0 3-5]
和[3 0 3-5]
都是C的成员,但它们的和[4 0 6-10]
(属于C)不是前面一个向量(例如[2 0 6-10]
的乘积。因此,世界上所有的rref
都无法解决您的问题
那么你能做些什么呢
你需要检查一下
(randn*subset(randn,randn)+randn*subset(randn,randn)))
是C的一个成员,除非我弄错了,否则这是一个困难的问题:从概念上讲,您需要遍历向量的每个元素,并确保它符合预定条件。或者,您可以尝试找到一个集合,使C(x1,x2)给出正确的答案。在这种情况下,您可以使用以数字方式解决此问题,并验证返回值是否在定义的公差范围内:
[s,error] = fminsearch(@(x) norm(C(x(1),x(2)) - [2 0 6 -10]),[1 1])
s =
1.999996976386119 6.000035034493023
error =
3.827680714104862e-05
编辑:您需要确保在乘法中可以使用负数,所以不要使用rand,而是使用其他值。我把它改为randn。我发现了一个问题,因为在测试中,您只需使用rand值检查一次。rands的本质是,它们可能会被不幸地选择用于你的测试。对于失败的测试C,你只需检查它是否是一维子空间。它失败了,因为子空间是二维的。@bdecaf那么如何测试它的二维性呢?显然你需要两行。它看起来像
subspaceTest=@(子集)single(rref([子集(rand,rand)+子集(rand,rand);子集(rand,rand)+子集(rand,rand)])…==单(rref([rand*子集(rand,rand);rand*子集(rand,rand)])
在您的符号中(只在每个子空间中添加了第二行)。很有趣。这似乎在大多数情况下都有效,但您并没有回答OP最初的问题:具体来说,您试图查看输出的秩是否等于输入的数目,这与验证子集是否闭合无关。您是否有一个案例不起作用?我希望它会在“几乎是一个子空间”的示例中给出误报(例如,它们将epsilon添加到其中一个组件),但这是使用浮点近似实数的一个限制。我认为我的答案是好的,因为(a)它很简单(b)它很一般,(c)它把数学巧妙地结合到代码中。啊哈@(x) [x^2,3*x^2]应该失败,因为-1*c(1)=[-1,-3],它在R中没有对应的点(您需要c(i))。但排名仍然是1。虽然努力很好,但理论还是赢得了胜利,非常感谢你的回答。我确信我理解如何正确阅读它。fminsearch是否自行填充x(1)和x(2),直到找到x1和x2值,该值给出一个向量,而该向量通过与另一个向量C相减得到一个单位向量。。?我可能有点困惑..fminsearch会找到最接近的点集,从而最小化错误。在这种情况下,它试图找到一个点,使C(x)尽可能接近[2 0 6-10]
。在这种情况下,误差很小,但在另一种情况下,误差可能很大,这意味着您的输入函数不是子空间。是否可以对其进行广义化,以便输入函数(在这种情况下为C)获得它接受的参数数。类似于[s,error]=fminsearch(@(func,varargs)norm(func(varargs)-[2 0 6-10]),[1]),它类似于在不声明每个arg的情况下创建C的子集。因此,如果一个函数应该存在,那么它可能是C(varargs('random'),而不是C(rand,rand)…-希望它有意义..???只要看看@我的评论就可以看出@(func,varargs)没有意义。。只需将其视为@(varargs),并且func(varargs)仍在范数内。@Norfeldt注意,我的答案并不是您所寻找的代码解决方案,而是建议您可以做什么。您需要多次运行类似的操作,并希望涵盖许多可能的解决方案,然后才能自信地找到正确的答案。Chris建议对100个不同的向量进行秩计算,虽然他的数字可能很大,但这是你在进行数字运算时付出的成本
[s,error] = fminsearch(@(x) norm(C(x(1),x(2)) - [2 0 6 -10]),[1 1])
s =
1.999996976386119 6.000035034493023
error =
3.827680714104862e-05