0

この質問に答えたとき、私の答えは次のように始まりました。

「初心者向け」のビットは、ベクトル化されたソリューションで編集を追加できると思ったからです。しかし、そうしようとすると、mrdivide (b/a) の使用をベクトル化する際に問題が発生しました。

私の質問(コードの下にマークされています)はb(z,:)/a(z,:)、ループを使用せずに解決できるかどうかです。b/aつまり、行列の各行を個別に解決します。

person = [98   206    35   114;
          60   206    28    52;
         100   210    31   116;
          69   217    26    35;
          88   213    42   100];

person1 = [93 208 34 107];

allNames = {'Cameron'; 'David'; 'Mike'; 'Bill'; 'Joe'};

n = 5;
a = max(person,repmat(person1,n,1));
b = min(person,repmat(person1,n,1));

for z = 1:5
    percent_error = b(z,:)/a(z,:);          %// Here is my question
    if percent_error >= 0.85
        disp(['Match, its ', allNames{z} ,'!'])
    end
end
4

2 に答える 2

1

操作をベクトル化することで、実際にループをなくすことができます。秘訣は、対角ブロック行列を操作することです。各ブロックは 1 行のみの行列です (毎回異なる行)。aおよび に対してこのようなブロック行列を作成した後b、次を使用できますmrdivide

% # Without loop
tic
A = zeros(size(a) * size(a, 1));
B = zeros(size(b) * size(b, 1));
V = ones(size(a, 2), 1) * (1:size(a, 1));
idx = (0:size(A, 1):numel(A) - 1) + (V(:)' - 1) * size(a, 1) + 1;
A(idx) = a';
B(idx) = b';
X = diag(B / A);
percent_error1 = X(1:size(a, 1):end);
toc

% # With loop
tic
percent_error2 = zeros(5, 1);
for z = 1:5
    percent_error2(z) = b(z,:) / a(z,:);
end
toc

結果は次のとおりです。

Elapsed time is 0.000160 seconds.
Elapsed time is 0.000048 seconds.

percent_error1 =
    0.9741
    0.8516
    0.9670
    0.8221
    0.9611

percent_error2 =
    0.9741
    0.8516
    0.9670
    0.8221
    0.9611

これは、大きな配列の行列除算がforループよりも時間がかかるケースの 1 つです。

于 2012-12-11T13:06:56.153 に答える
0

私はこれについて考えていました:

person/person1

しかし、これは、person のすべてのインデックスが person1 の対応するインデックスよりも大きい場合にのみ、良い結果をもたらします。

于 2012-12-11T10:45:53.863 に答える