0

プログラマーとして数学を学ぶ方法として、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 が機能していません (1 つの引数しか受け入れない場合にのみ機能します)。numArgs の私の解決策が最適ではないことはわかっていますが、現時点で思いついたものでした..

このコードを最適化して C が適切に動作し、おそらく2 つ以上の引数のelseifステートメントを回避する方法はありますか?

PS: 穴のことをやってくれる組み込みの matlab 関数が見つからなかったようです..

4

2 に答える 2

1

最適ではないという解決策は、問題の表面をかすめただけです。

一度にやりすぎていると思います。rref使用すべきではなく、すべてを複雑にしています。特にnumArgs1 より大きい場合。

考えてみてください:[1 0 3 -5][3 0 3 -5]はどちらも C のメンバーですが、それらの合計[4 0 6 -10](C に属します) は、前のベクトルの 1 つの乗算の線形積ではありません (例: [2 0 6 -10])。ですからrref、世界中のすべての人があなたの問題を解決することはできません。

代わりに何ができますか?

かどうかを確認する必要があります

(randn*subset(randn,randn)+randn*subset(randn,randn))) 

は C のメンバーです。私が間違っていない限り、これは難しい問題です。概念的には、ベクトルのすべての要素を繰り返し処理し、所定の条件に一致することを確認する必要があります。または、C(x1,x2) が正しい答えを与えるようなセットを見つけようとすることもできます。この場合、fminsearchを使用してこの問題を数値的に解き、戻り値が定義された許容範囲内にあることを確認できます。

[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 を使用しないで、別のものを使用してください。ランドに変更しました。

于 2012-05-30T12:33:39.020 に答える
1

これが1つのアプローチです。指定された関数が線形部分空間を表すかどうかをテストします。技術的には、これは確率論的テストにすぎませんが、失敗する可能性はほとんどありません。

まず、適切な抽象化を定義します。この高階関数は、最初の引数として関数を取り、その関数を行列のすべての行に適用しますxfuncこれにより、同時に多くの引数をテストできます。

function y = apply(func,x)
  for k = 1:size(x,1)
    y(k,:) = func(x(k,:));
  end

次にコア関数を書きます。以下は、 のベクトルを返すfunc1 つの引数 ( のベクトルであると推定される) の関数です。ランダムに選択された 100 個のベクトルに適用して、出力行列を取得します。が線形部分空間を表す場合、出力のランクは より小さいか等しくなります。R^mR^nfuncR^mfuncm

function result = isSubspace(func,m)
  inputs  = rand(100,m);
  outputs = apply(func,inputs);
  result  = rank(outputs) <= m;

ここでそれが実行されます。関数は引数を 1 つしかとらないことに注意してください - あなたが書いたところc(x1,x2)=[x1,0,x2]に I write を書きましc(x) = [x(1),0,x(2)]たが、これは少し冗長ですが、関数が持つ引数の数を決定するために if ステートメントをいじる必要がないという利点があります - そしてこれは機能します1 または 2 だけでなくR^m、任意の の入力を受け取る関数の場合。m

>> v = @(x) [x,3*x]
>> isSubspace(v,1)
ans =
     1

>> a = @(x) [x(1),3*x(1)+1]
>> isSubspace(a,1)
ans =
     0

>> c = @(x) [x(1),0,x(2),-5*x(1)]
>> isSubspace(c,2)
ans =
     1
于 2012-05-30T11:59:52.407 に答える