backslash (\) 左行列除算: exact or least square solution

## 呼び出し手順

    X = A \ B

## 説明

バックスラッシュは左行列除算を定義します. `X=A\B` は `A*X=B`の解です.

`A` が正方で非特異の場合, `X=A\B` は `X=inv(A)*B` と等価です.しかし,計算はより正確で浮動小数点演算の負荷は小さくなります. すなわち,線形システムの方程式`A*X=B`の解を計算する際には, バックスラッシュ演算子を使用するべきであり,`inv`関数の 使用は避けるべきです.

`A`が正方の場合, 解`X`は LU分解または線形最小二乗ソルバのどちらかにより計算できます. `A`の条件数が`1/(10*%eps)`よりも小さい場合 (つまり,`A`の条件が良い場合),ピボット選択付きLU分解が使用されます. そうでない場合(`A`の条件が悪い場合), `X` は`A`の完全直交分解を用いて `||A*X-B||`を最小化する最小ノルム解となります (すなわち,`X`は線形最小二乗問題の解です).

`A` が正方でない場合, `X` は最小二乗解となります. すなわち, `norm(A*X-B)` は,最小値 (ユークリッドノルム)となります. `A` が列フルランクの場合,最小二乗解, `X=A\B`, は 唯一の解 (`norm(A*X-B)`を最小化する唯一の `X`が存在)となります. `A` が列フルランクでない場合, 最小二乗解は唯一ではなくなり, `X=A\B`は一般に最小ノルム解ではなくなります (最小ノルム解は `X=pinv(A)*B`です).

`A.\B` は`(i,j)` エントリが `A(i,j)\B(i,j)`となる行列となります. `A.\B` は `A*ones(B).\B` (または `A.\(B*ones(A))` と等価になります.

`A\.B` は定義されていない演算子です. この演算子は, `*` または `/` のように 新しい演算子を定義する際に使用できます (オーバーロード参照).

## 例

    A=[
       9.   -36.    30.
      -36.   192.  -180.
       30.  -180.   180.
    ];
    b=[
       3.
      -24.
       30.
    ];
    x=A\b
    A*x-b // ゼロに近い

    A=rand(3,2);
    b=[1;1;1];
    x=A\b;
    y=pinv(A)*b;
    x-y
    A=rand(2,3);b=[1;1];
    x=A\b;
    y=pinv(A)*b;
    x-y, A*x-b, A*y-b

    // ランク落ちの場合
    A=rand(3,1)*rand(1,2);
    b=[1;1;1];
    x=A\b;
    y=pinv(A)*b;
    A*x-b, A*y-b
    A=rand(2,1)*rand(1,3);
    b=[1;1];
    x=A\b;
    y=pinv(A)*b;
    A*x-b, A*y-b

    // 複数の線形ソルバのベンチマーク

    [A,descr,ref,mtype] = ReadHBSparse(SCI+"/modules/umfpack/demos/bcsstk24.rsa");
    b = zeros(size(A,1),1);

    tic();
    res = umfpack(A,'\',b);
    mprintf('\nTime with umfpack: %.3f\n',toc());

    tic();
    res = linsolve(A,b);
    mprintf('\ntime with linsolve: %.3f\n',toc());

    tic();
    res = A\b;
    mprintf('\ntime with backslash: %.3f\n',toc());

## 参照

- slash
- lsq
- inv
- pinv
- linsolve
- umfpack
- datafit
- kron .\.
- overloading

## 履歴

5.5.0 バックスラッシュの条件数の閾値が増加しました.