<?xml version="1.0" encoding="UTF-8"?>
<!--
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2008 - INRIA
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 -->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="schur">
    <refnamediv>
        <refname>schur</refname>
        <refpurpose>[ordered] Schur decomposition of matrix and pencils</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>[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 [,Z,dim]] = schur(A,E,flag)
            [Z,dim] = schur(A,E,flag)
            [As,Es [,Z,dim]]= schur(A,E,extern2)
            [Z,dim]= schur(A,E,extern2)
        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Arguments</title>
        <variablelist>
            <varlistentry>
                <term>A</term>
                <listitem>
                    <para>real or complex square matrix.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>E</term>
                <listitem>
                    <para>
                        real or complex square matrix with same dimensions as <literal> A</literal>.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>flag</term>
                <listitem>
                    <para>
                        character string (<literal>'c'</literal> or <literal>'d'</literal>)
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>extern1</term>
                <listitem>
                    <para>an ``external'', see below</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>extern2</term>
                <listitem>
                    <para>an ``external'', see below</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>U</term>
                <listitem>
                    <para>orthogonal or unitary square matrix</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>Q</term>
                <listitem>
                    <para>orthogonal or unitary square matrix</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>Z</term>
                <listitem>
                    <para>orthogonal or unitary square matrix</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>T</term>
                <listitem>
                    <para>upper triangular or quasi-triangular square matrix</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>As</term>
                <listitem>
                    <para>upper triangular or quasi-triangular square matrix</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>Es</term>
                <listitem>
                    <para>upper triangular  square matrix</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>dim</term>
                <listitem>
                    <para>integer</para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        <para>
            Schur forms, ordered Schur forms of matrices and pencils
        </para>
        <variablelist>
            <varlistentry>
                <term>MATRIX SCHUR FORM</term>
                <listitem>
                    <variablelist>
                        <varlistentry>
                            <term>Usual schur form:</term>
                            <listitem>
                                <para>
                                    <literal>[U,T] = schur(A)</literal> produces a Schur matrix
                                    <literal>T</literal> and a unitary matrix <literal>U</literal> so that
                                    <literal>A = U*T*U'</literal> and <literal>U'*U =  eye(U)</literal>. By itself, schur(<literal>A</literal>) returns
                                    <literal>T</literal>. If <literal>A</literal> is complex, the Complex
                                    Schur Form is returned in matrix
                                    <literal>T</literal>. The Complex Schur Form is upper triangular with
                                    the eigenvalues of <literal>A</literal> on the diagonal. If
                                    <literal>A</literal> is real, the Real Schur Form is returned.  The Real
                                    Schur Form has the real eigenvalues on the diagonal and the
                                    complex eigenvalues in 2-by-2 blocks on the diagonal.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Ordered Schur forms</term>
                            <listitem>
                                <para>
                                    <literal>[U,dim]=schur(A,'c')</literal> returns an unitary
                                    matrix <literal>U</literal> which transforms <literal>A</literal> into schur
                                    form.  In addition, the dim first columns of <literal>U</literal> make
                                    a basis of the eigenspace of <literal>A</literal> associated with
                                    eigenvalues with negative real parts (stable "continuous
                                    time" eigenspace).
                                </para>
                                <para>
                                    <literal>[U,dim]=schur(A,'d')</literal> returns an unitary
                                    matrix <literal>U</literal> which transforms <literal>A</literal> into schur
                                    form.  In addition, the <literal>dim</literal> first columns of
                                    <literal>U</literal> span a basis of the eigenspace of <literal>A</literal>
                                    associated with eigenvalues with magnitude lower than 1 (stable
                                    "discrete time" eigenspace).
                                </para>
                                <para>
                                    <literal>[U,dim]=schur(A,extern1)</literal> returns an unitary matrix
                                    <literal>U</literal> which transforms <literal>A</literal> into schur form.
                                    In addition, the <literal>dim</literal> first columns of
                                    <literal>U</literal> span a basis of the eigenspace of <literal>A</literal>
                                    associated with the eigenvalues which are selected by the
                                    external function <literal>extern1</literal> (see external for
                                    details).  This external can be described by a Scilab function
                                    or by C or Fortran procedure:
                                </para>
                                <variablelist>
                                    <varlistentry>
                                        <term>a Scilab function</term>
                                        <listitem>
                                            <para>
                                                If <literal>extern1</literal> is described by a Scilab function, it
                                                should have the following syntax:
                                                <literal>s=extern1(Ev)</literal>, where <literal>Ev</literal> is an eigenvalue and
                                                <literal>s</literal> a boolean.
                                            </para>
                                        </listitem>
                                    </varlistentry>
                                    <varlistentry>
                                        <term>a C or Fortran procedure</term>
                                        <listitem>
                                            <para>
                                                If <literal>extern1</literal> is described by a C or Fortran function it
                                                should have the following syntax:
                                                <literal>int extern1(double *EvR, double *EvI)</literal>
                                                where <literal>EvR</literal> and <literal>EvI</literal> are  eigenvalue real and complex parts.
                                                a true or non zero returned value stands for selected eigenvalue.
                                            </para>
                                        </listitem>
                                    </varlistentry>
                                </variablelist>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>PENCIL SCHUR FORMS</term>
                <listitem>
                    <variablelist>
                        <varlistentry>
                            <term>Usual Pencil Schur form</term>
                            <listitem>
                                <para>
                                    <literal>[As,Es] = schur(A,E)</literal> produces a quasi triangular
                                    <literal>As</literal> matrix and a triangular <literal>Es</literal> matrix
                                    which are the generalized Schur form of the pair <literal>A, E</literal>.
                                </para>
                                <para>
                                    <literal>[As,Es,Q,Z] = schur(A,E)</literal>
                                    returns in addition two unitary matrices
                                    <literal>Q</literal> and <literal>Z</literal> such that
                                    <literal>As=Q'*A*Z</literal> and <literal>Es=Q'*E*Z</literal>.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>Ordered Schur forms:</term>
                            <listitem>
                                <para>
                                    <literal>[As,Es,Z,dim] = schur(A,E,'c')</literal>
                                    returns the real generalized
                                    Schur form of the pencil <literal>s*E-A</literal>. In addition, the dim first columns
                                    of <literal>Z</literal> span a basis of the right eigenspace  associated with
                                    eigenvalues with negative real parts (stable "continuous
                                    time" generalized eigenspace).
                                </para>
                                <para>
                                    <literal>[As,Es,Z,dim] = schur(A,E,'d')</literal>
                                </para>
                                <para>
                                    returns the real generalized
                                    Schur form of the pencil <literal>s*E-A</literal>. In addition, the dim first columns
                                    of <literal>Z</literal> make a basis of the right eigenspace  associated with
                                    eigenvalues with magnitude lower than 1 (stable "discrete
                                    time" generalized eigenspace).
                                </para>
                                <para>
                                    <literal>[As,Es,Z,dim] = schur(A,E,extern2)</literal>
                                </para>
                                <para>
                                    returns the real generalized Schur form of the pencil <literal>s*E-A</literal>.
                                    In addition, the dim first columns
                                    of <literal>Z</literal> make a basis of the right eigenspace  associated with
                                    eigenvalues of the pencil which are selected according to a
                                    rule which is given by the function <literal>extern2</literal>. (see external
                                    for details). This external can be described by a Scilab
                                    function or by C or Fortran procedure:
                                </para>
                                <variablelist>
                                    <varlistentry>
                                        <term>A Scilab function</term>
                                        <listitem>
                                            <para>
                                                If <literal>extern2</literal> is described by a Scilab function, it should
                                                have the following syntax:
                                                <literal>s=extern2(Alpha,Beta)</literal>, where <literal>Alpha</literal> and
                                                <literal>Beta</literal> defines a generalized eigenvalue and
                                                <literal>s</literal> a boolean.
                                            </para>
                                        </listitem>
                                    </varlistentry>
                                    <varlistentry>
                                        <term>C or Fortran procedure</term>
                                        <listitem>
                                            <para>
                                                if external <literal>extern2</literal> is described by a C or a
                                                Fortran procedure, it should have the following calling
                                                sequence:
                                            </para>
                                            <para>
                                                <literal>int extern2(double *AlphaR, double *AlphaI, double *Beta)</literal>
                                            </para>
                                            <para>
                                                if <literal>A</literal> and <literal>E</literal> are real and
                                            </para>
                                            <para>
                                                <literal>int extern2(double *AlphaR, double *AlphaI, double *BetaR, double *BetaI)</literal>
                                            </para>
                                            <para>
                                                if <literal>A</literal> or <literal>E</literal> are complex.
                                                <literal>Alpha</literal>, and <literal>Beta</literal> defines the generalized eigenvalue.
                                                a true or non zero returned value stands for selected generalized eigenvalue.
                                            </para>
                                        </listitem>
                                    </varlistentry>
                                </variablelist>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>References</title>
        <para>
            Matrix schur form computations are based on the Lapack routines DGEES and ZGEES.
        </para>
        <para>
            Pencil schur form computations are based on the Lapack routines DGGES and ZGGES.
        </para>
    </refsection>
    <refsection>
        <title>Examples</title>
        <programlisting role="example"><![CDATA[
//SCHUR FORM OF A MATRIX
//----------------------
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)      //stable cont. eigenvalues

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

// The same function in C (a Compiler is required)
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')


//build and link
lp=ilib_for_link('mytest','mytest.c',[],'c');
link(lp,'mytest','c');

//run it
[U,dim,T]=schur(A,'mytest');
//SCHUR FORM OF A PENCIL
//----------------------
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 //It is 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)

//the same function in Fortran (a Compiler is required)
ftn=['integer function mytestf(ar,ai,b)' //the fortran code
     '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');

//run it

[As,Es,Z,dim] = schur(A,E,'mytestf')
 ]]></programlisting>
    </refsection>
    <refsection role="see also">
        <title>See also</title>
        <simplelist type="inline">
            <member>
                <link linkend="spec">spec</link>
            </member>
            <member>
                <link linkend="bdiag">bdiag</link>
            </member>
            <member>
                <link linkend="ricc">ricc</link>
            </member>
            <member>
                <link linkend="pbig">pbig</link>
            </member>
            <member>
                <link linkend="psmall">psmall</link>
            </member>
        </simplelist>
    </refsection>
</refentry>
