# schur

行列およびペンシルの[ソートされた] Schur 分解

## 呼び出し手順

    [U,T] = schur(A)
                [U,dim [,T] ]=schur(A,flag)
                [U,dim [,T] ]=schur(A,extern1)

                [As,Es [,Q,Z]]=schur(A,E)
                [As,Es [,Q],Z,dim] = schur(A,E,flag)
                [Z,dim] = schur(A,E,flag)
                [As,Es [,Q],Z,dim]= schur(A,E,extern2)
                [Z,dim]= schur(A,E,extern2)

## パラメータ

A

  実数または複素数の正方行列.

E

  `A`と同じ次元の実数または複素数の正方行列.

flag

  文字列 (`'c'` または `'d'`)

extern1

  an ``external'', 以下の参照

extern2

  an ``external'', 以下の参照

U

  直交またはユニタリ正方行列

Q

  直交またはユニタリ正方行列

Z

  o直交またはユニタリ正方行列

T

  上三角または準三角正方行列

As

  上三角または準三角正方行列

Es

  上三角正方行列

dim

  整数

## 説明

Schur 形式, 行列およびペンシルのソートされた Schur 形式

行列Schur形式
  通常のSchur形式:

    `[U,T] = schur(A)` は, `A = U*T*U'` および `U'*U = eye(U)`となるような Schur行列`T` およびユニタリ行列 `U` を出力します. Schur(`A`)は,`T`を返します. `A` が複素数の場合, 複素Schur形式は,行列`T`に返します. 複素Schur形式は,`A`の固有値を対角項に有する上三角行列です. `A` が実数の場合, 実数Schur形式が返されます. 実数Schur形式は,対角項に実数固有値、複素数固有値を対角項の2x2ブロックに 有します.

  ソートされたSchur形式

    `[U,dim]=schur(A,'c')` は, `A`を Schur 形式に変換する ユニタリ行列 `U` を返します. 更に,`U`の最初の列 dim は, 実部が負の固有値(安定な"連続時間"固有値空間) に関連する`A`の固有値空間 の基底を構成します.

    `[U,dim]=schur(A,'d')` は, `A`を Schur 形式に変換する ユニタリ行列 `U` を返します. 更に,`U`の最初の列 dim は, 大きさが1未満の固有値(安定な"離散時間"固有値空間) に関連する`A`の固有値空間 の基底を構成します.

    `[U,dim]=schur(A,extern1)` は, `A`を Schur 形式に変換する ユニタリ行列`U`を返します. 更に,`U`の最初の列 dim は, 外部関数 `extern1` (詳細は external 参照) により選択された固有値に関連する`A`の固有値空間 の基底を構成します. この external はScilab関数またはCまたはFortranプロシージャにより 次のように記述することができます:

    Scilab関数

      `extern1`が Scilab関数により記述される場合, 以下の呼び出し手順を有する必要があります: `s=extern1(Ev)`, ただし `Ev` は固有値, `s` は論理値です.

    C または Fortran プロシージャ

      `extern1` がCまたはFortran関数により 記述される場合,以下の呼び出し手順を有する必要があります: `int extern1(double *EvR, double *EvI)` ただし `EvR` および `EvI` は 固有値の実部および虚部です. trueまたはゼロでない戻り値は,選択された固有値を意味します.

ペンシルSchur形式
  通常のペンシルSchur形式

    `[As,Es] = schur(A,E)` は, 対`A, E`の一般化Schur形式である 準三角行列`As`行列および三角行列`Es` を出力します.

    `[As,Es,Q,Z] = schur(A,E)`は,更に `As=Q'*A*Z` および `Es=Q'*E*Z`となるような 2つのユニタリ行列`Q` および `Z`を返します.

  ソートされたSchur形式:

    `[As,Es,Z,dim] = schur(A,E,'c')`は, ペンシル`s*E-A`の実数一般化Schur形式を返します. 更に, `Z`の最初の列 dim は, 実部が負の固有値 (安定な"連続時間"一般化固有値空間)に関連する 固有値空間の基底を構成します.

    `[As,Es,Z,dim] = schur(A,E,'d')`

    は,ペンシル`s*E-A`の 実数一般化Schur形式を返します. 更に, `Z`の最初の列 dim は, 大きさ1未満の固有値 (安定な"離散時間"一般化固有値空間)に関連する 固有値空間の基底を構成します.

    `[As,Es,Z,dim] = schur(A,E,extern2)`

    は,ペンシル`s*E-A`の実一般化Schur形式を返します. 更に, `Z`の最初の列 dim は, 関数`extern2`により指定された規則に基づき選択された ペンシルの固有値に関する固有値空間の基底を構成します. (詳細は external 参照) この external は Scilab 関数またはCまたはFortranプロシージャ により次のように記述することができます:

    Scilab関数

      `extern2`がScilab関数により記述される場合, 以下の呼び出し手順を有する必要があります: `s=extern2(Alpha,Beta)`, ただし `Alpha` および `Beta` は一般化固有値および論理値 `s` を定義します.

    C またはFortranプロシージャ

      if external `extern2` がCまたはFortran関数により 記述される場合,以下の呼び出し手順を有する必要があります:

      `int extern2(double *AlphaR, double *AlphaI, double *Beta)`

      : `A` および `E` が実数の場合.

      `int extern2(double *AlphaR, double *AlphaI, double *BetaR, double *BetaI)`

      : `A` および `E` が複素数の場合. `Alpha`, および `Beta` は一般化固有値を定義します. trueまたは非ゼロの戻り値は,選択された一般化固有値を意味します.

## 参考

行列Schur形式の計算はLapackルーチンDGEES および ZGEESに基づいています.

ペンシルSchur形式の計算はLapackルーチンDGGES および ZGGESに基づいています.

## 例

    //行列Schur形式
    //----------------------
    A=diag([-0.9,-2,2,0.9]);X=rand(A);A=inv(X)*A*X;
    [U,T]=schur(A);T

    [U,dim,T]=schur(A,'c');
    T(1:dim,1:dim)      //安定な連続時間固有値

    function t=mytest(Ev),t=abs(Ev)<0.95,endfunction
    [U,dim,T]=schur(A,mytest);
    T(1:dim,1:dim)

    // Cの同じ関数 (コンパイラが必要)
    cd TMPDIR;
    C=['int mytest(double *EvR, double *EvI) {' //the C code
       'if (*EvR * *EvR + *EvI * *EvI < 0.9025) return 1;'
       'else return 0; }';]
    mputl(C,TMPDIR+'/mytest.c')

    //構築/リンク
    lp=ilib_for_link('mytest','mytest.c',[],'c');
    link(lp,'mytest','c');

    //実行
    [U,dim,T]=schur(A,'mytest');
    //ペンシルのSchur形式
    //----------------------
    F=[-1,%s, 0,   1;
        0,-1,5-%s, 0;
        0, 0,2+%s, 0;
        1, 0, 0, -2+%s];
    A=coeff(F,0);E=coeff(F,1);
    [As,Es,Q,Z]=schur(A,E);
    Q'*F*Z //これはAs+%s*Esです

    [As,Es,Z,dim] = schur(A,E,'c')
    function t=mytest(Alpha,Beta),t=real(Alpha)<0,endfunction
    [As,Es,Z,dim] = schur(A,E,mytest)

    //Fortranの同じ関数 (コンパイラが必要)
    ftn=['integer function mytestf(ar,ai,b)' //fortranコード
         'double precision ar,ai,b'
         'mytestf=0'
         'if(ar.lt.0.0d0) mytestf=1'
         'end']
    mputl('      '+ftn,TMPDIR+'/mytestf.f')

    //build and link
    lp=ilib_for_link('mytestf','mytestf.f',[],'F');
    link(lp,'mytestf','f');

    //実行

    [As,Es,Z,dim] = schur(A,E,'mytestf')

## 参照

- spec
- bdiag
- ricc
- pbig
- psmall