Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB:测试匿名向量是否是R^n的子集_Matlab_Math_Vector - Fatal编程技术网

MATLAB:测试匿名向量是否是R^n的子集

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

作为一名程序员,我试图使用MatLab代码作为学习数学的一种方式

所以我在读这篇关于子空间的文章,并试图构建一些简单的matlab函数来为我做到这一点

以下是我取得的成绩:

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