⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 null.src

📁 没有说明
💻 SRC
字号:
/*
** null.src - Null space using QR decomposition.
** (C) Copyright 1988-1998 by Aptech Systems, Inc.
** All Rights Reserved.
**
** This Software Product is PROPRIETARY SOURCE CODE OF APTECH
** SYSTEMS, INC.    This File Header must accompany all files using
** any portion, in whole or in part, of this Source Code.   In
** addition, the right to create such files is strictly limited by
** Section 2.A. of the GAUSS Applications License Agreement
** accompanying this Software Product.
**
** If you wish to distribute any portion of the proprietary Source
** Code, in whole or in part, you must first obtain written
** permission from Aptech Systems.
**
** These functions require GAUSS-386.
**
**    Format                                  Line
**  ===============================================
**   b = NULL(x);                              28
**   nu = NULL1(x,dataset);                   205
*/

#include qr.ext

/*
**> null
**
**  Purpose:    Computes an orthonormal basis for the (right) null
**              space of a matrix.
**
**  Format:     b = null(x);
**
**  Input:      x    NxM matrix.
**
**  Output:     b    MxK matrix, where K is the nullity of X, such
**                   that:
**
**                       x*b = 0         ( NxK matrix of zeros )
**                         and
**                       b'b = I         ( MxM identity matrix )
**
**              The error returns are returned in b:
**
**                  error code              reason
**                  -------------------------------------------------
**                      1                there is no null space
**
**                      2                b is too large to return
**                                       in a single matrix
**
**              Use scalerr to test for error returns.
**
**  Remarks:    The orthogonal complement of the column space of x' is
**              computed using the QR decomposition.  This provides an
**              orthonormal basis for the null space of x.
**
**  Globals:    _qrcd, _qrsl
**
**  Example:    let x[2,4] = 2 1 3 -1
**                           3 5 1  2;
**
**              b = null(z);
**              z = x*b;
**              i = b'b;
*/

proc null(x);
    local r,e,tol,indx,sqr,diff,nullity,flag,narg,parg,qraux,
        work,jpvt,job,karg,dum,info,qy,
        rm,q1,i,y,cdim;

    /* check for complex input */
    if iscplx(x);
        if hasimag(x);
            errorlog "ERROR: Not implemented for complex matrices.";
            end;
        else;
            x = real(x);
        endif;
    endif;

    tol = 2.24e-16*sqrt( sumc( sumc( x.*x ) ) );    /* use F-norm */

    /* the following code computes QR decomposition */

    flag = 1;       /* always do pivoting */

    /* compute matrix dimensions and other inputs to qrdc subroutine  */
    /* rows and cols reversed, since we want QR of x' */
    narg = cols(x);          /* leading dimension of x matrix */
    parg = rows(x);         /* order of x matrix */
    qraux = zeros(parg,1);
    work = qraux;
    jpvt = qraux;           /* all columns are to be free */

    /* compute matrix dimensions and other inputs to qrsl subroutine  */

    karg = parg;
    dum = 0;
    info = 0;
    job = 10000;    /* compute qy only */
    qy = zeros(narg,1);

    /* matrix already transposed for this purpose */

    /* call fortran routine to perform transform */

#ifDLLCALL
#else

    if rows(_qrdc) /= 647 or _qrdc[1] $== 0;
        _qrdc = zeros(647,1);
        loadexe _qrdc = qrdc.rex;
    endif;
    callexe _qrdc(x,narg,narg,parg,qraux,jpvt,work,flag);

#endif

#ifDLLCALL

    dllcall qrdc(x,narg,narg,parg,qraux,jpvt,work,flag);

#endif

    if narg >= parg;        /* case 1: more rows than cols (in transpose) */
        diff = narg-parg;
        rm = trimr(x',0,diff);      /* R except for part below diag  */
        r = diag(rm);       /* Diagonals */
        cdim = parg;
    else;           /* case 2: more cols than rows (in transpose) */
        diff = parg-narg;
        rm = trimr(x,0,diff)';      /* R except for part below diag  */
        r = diag(rm);       /* Diagonals */
        cdim = narg;
    endif;

    /* find 0's of r */
    sqr = seqa(1,1,rows(r));
    e = abs( r ) .<= tol;
    indx = ( submat(packr( sqr~miss(e,0) ),0,1) );

    if narg >= parg;
        if ismiss(indx);
            nullity = diff;
        else;
            nullity = diff + rows(indx);
        endif;
    else;
        if ismiss(indx);
            nullity = 0;
        else;
            nullity = rows(indx);
        endif;
    endif;

    if nullity == 0;
        retp( error(1) );           /* return scalar error code 1 */
    endif;

    y = shiftr(1~zeros(1,narg-1),narg-nullity,0);

    if narg*nullity > 8190;
        retp( error(2) );
    endif;

    q1 = zeros(narg,nullity);       /* initialize space for q1 */
    i = 1;

#ifDLLCALL
#else

    if rows(_qrsl) /= 455 or _qrsl[1] $== 0;
        _qrsl = zeros(455,1);
        loadexe _qrsl = qrsl.rex;
    endif;

#endif

    /* go through loop to compute Q1 */
    do until i > nullity;

#ifDLLCALL
#else

        callexe _qrsl(x,narg,narg,karg,qraux,y,qy,dum,dum,dum,dum,job,info);

#endif

#ifDLLCALL

        dllcall qrsl(x,narg,narg,karg,qraux,y,qy,dum,dum,dum,dum,job,info);

#endif

        q1[.,i] = qy;
        y = shiftr(y,1,0);
        i = i + 1;
    endo;
    retp( q1 );
endp;

/*
**> null1
**
**  Purpose:    Computes an orthonormal basis for the (right) null
**              space of a matrix.
**
**  Format:     nu = null1(x,dataset);
**
**  Input:      x          NxM matrix.
**
**  Output:     nu         scalar, the nullity of x.
**
**              dataset    string, the name of a data set where the transpose
**                         of b is written.  The matrix b is an MxK matrix,
**                         where K is the nullity of X, such that:
**
**                              x*b = 0      ( NxK matrix of zeros )
**                                and
**                              b'b = I      ( MxM identity matrix )
**
**                         If the nullity of the matrix is zero, no
**                         data set will be written.
**
**  Globals:    _qrdc, _qrsl
*/

proc null1(x,dataset);
    local r,e,tol,indx,sqr,diff,nullity,f1,flag,narg,parg,qraux,
        work,jpvt,job,karg,dum,info,qy,
        rm,i,y,cdim;

    /* check for complex input */
    if iscplx(x);
        if hasimag(x);
            errorlog "ERROR: Not implemented for complex matrices.";
            end;
        else;
            x = real(x);
        endif;
    endif;

    tol = 2.24e-16*sqrt( sumc( sumc( x.*x ) ) );    /* use F-norm */

    /* The following code computes QR decomposition */

    flag = 1;       /* always do pivoting */

    /* compute matrix dimensions and other inputs to qrdc subroutine with
    :: rows and cols reversed, since we want QR of x'
    */
    narg = cols(x);          /* leading dimension of x matrix */
    parg = rows(x);         /* order of x matrix */
    qraux = zeros(parg,1);
    work = qraux;
    jpvt = qraux;           /* all columns are to be free */

    /* compute matrix dimensions and other inputs to qrsl subroutine  */

    karg = parg;
    dum = 0;
    info = 0;
    job = 10000;    /* compute qy only */
    qy = zeros(narg,1);

    /* matrix already transposed for this purpose */

    /* call routine to perform transform */

#ifDLLCALL
#else

    if rows(_qrdc) /= 647 or _qrdc[1] $== 0;
        _qrdc = zeros(647,1);
        loadexe _qrdc = qrdc.rex;
    endif;
    callexe _qrdc(x,narg,narg,parg,qraux,jpvt,work,flag);

#endif

#ifDLLCALL

    dllcall qrdc(x,narg,narg,parg,qraux,jpvt,work,flag);

#endif

    if narg >= parg;        /* case 1: more rows than cols (in transpose) */
        diff = narg-parg;
        rm = trimr(x',0,diff);      /* R except for part below diag  */
        r = diag(rm);       /* Diagonals */
        cdim = parg;
    else;           /* case 2: more cols than rows (in transpose) */
        diff = parg-narg;
        rm = trimr(x,0,diff)';      /* R except for part below diag  */
        r = diag(rm);       /* Diagonals */
        cdim = narg;
    endif;

    /* find 0's of r */
    sqr = seqa(1,1,rows(r));
    e = abs( r ) .<= tol;
    indx = ( submat(packr( sqr~miss(e,0) ),0,1) );

    if narg >= parg;
        if ismiss(indx);
            nullity = diff;
        else;
            nullity = diff + rows(indx);
        endif;
    else;
        if ismiss(indx);
            nullity = 0;
        else;
            nullity = rows(indx);
        endif;
    endif;

    if nullity == 0;
        retp( 0 );           /* return 0, no data set written */
    endif;

    y = shiftr(1~zeros(1,narg-1),narg-nullity,0);

    /* Write result to data set on disk. The number of rows in the data set
    :: is the nullity of the matrix
    */

    create f1 = ^dataset with x,narg,8;     /* create data set to hold result */
    i = 1;

#ifDLLCALL
#else

    if rows(_qrsl) /= 455 or _qrsl[1] $== 0;
        _qrsl = zeros(455,1);
        loadexe _qrsl = qrsl.rex;
    endif;

#endif

    /* go through loop to compute Q1 */
    do until i > nullity;

#ifDLLCALL
#else

        callexe _qrsl(x,narg,narg,karg,qraux,y,qy,dum,dum,dum,dum,job,info);

#endif

#ifDLLCALL

        dllcall qrsl(x,narg,narg,karg,qraux,y,qy,dum,dum,dum,dum,job,info);

#endif

        if writer(f1,qy') /= 1;     /* write result to row of disk  */
            errorlog "ERROR: Disk Full.";
            end;
        endif;
        y = shiftr(y,1,0);
        i = i + 1;
    endo;

    f1 = close(f1);
    retp( nullity );        /* return nullity */
endp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -