Exemple #1
0
void dqrdc ( double a[], int lda, int n, int p, double qraux[], int jpvt[], 
  double work[], int job )

/******************************************************************************/
/*
  Purpose:

    DQRDC computes the QR factorization of a real rectangular matrix.

  Discussion:

    DQRDC uses Householder transformations.

    Column pivoting based on the 2-norms of the reduced columns may be
    performed at the user's option.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    07 June 2005

  Author:

    C version by John Burkardt.

  Reference:

    Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart,
    LINPACK User's Guide,
    SIAM, (Society for Industrial and Applied Mathematics),
    3600 University City Science Center,
    Philadelphia, PA, 19104-2688.
    ISBN 0-89871-172-X

  Parameters:

    Input/output, double A(LDA,P).  On input, the N by P matrix
    whose decomposition is to be computed.  On output, A contains in
    its upper triangle the upper triangular matrix R of the QR
    factorization.  Below its diagonal A contains information from
    which the orthogonal part of the decomposition can be recovered.
    Note that if pivoting has been requested, the decomposition is not that
    of the original matrix A but that of A with its columns permuted
    as described by JPVT.

    Input, int LDA, the leading dimension of the array A.  LDA must
    be at least N.

    Input, int N, the number of rows of the matrix A.

    Input, int P, the number of columns of the matrix A.

    Output, double QRAUX[P], contains further information required
    to recover the orthogonal part of the decomposition.

    Input/output, integer JPVT[P].  On input, JPVT contains integers that
    control the selection of the pivot columns.  The K-th column A(*,K) of A
    is placed in one of three classes according to the value of JPVT(K).
      > 0, then A(K) is an initial column.
      = 0, then A(K) is a free column.
      < 0, then A(K) is a final column.
    Before the decomposition is computed, initial columns are moved to
    the beginning of the array A and final columns to the end.  Both
    initial and final columns are frozen in place during the computation
    and only free columns are moved.  At the K-th stage of the
    reduction, if A(*,K) is occupied by a free column it is interchanged
    with the free column of largest reduced norm.  JPVT is not referenced
    if JOB == 0.  On output, JPVT(K) contains the index of the column of the
    original matrix that has been interchanged into the K-th column, if
    pivoting was requested.

    Workspace, double WORK[P].  WORK is not referenced if JOB == 0.

    Input, int JOB, initiates column pivoting.
    0, no pivoting is done.
    nonzero, pivoting is done.
*/
{
  int j;
  int jp;
  int l;
  int lup;
  int maxj;
  double maxnrm;
  double nrmxl;
  int pl;
  int pu;
  int swapj;
  double t;
  double tt;

  pl = 1;
  pu = 0;
/*
  If pivoting is requested, rearrange the columns.
*/
  if ( job != 0 )
  {
    for ( j = 1; j <= p; j++ )
    {
      swapj = ( 0 < jpvt[j-1] );

      if ( jpvt[j-1] < 0 )
      {
        jpvt[j-1] = -j;
      }
      else
      {
        jpvt[j-1] = j;
      }

      if ( swapj )
      {
        if ( j != pl )
        {
          dswap ( n, a+0+(pl-1)*lda, 1, a+0+(j-1), 1 );
        }
        jpvt[j-1] = jpvt[pl-1];
        jpvt[pl-1] = j;
        pl = pl + 1;
      }
    }
    pu = p;

    for ( j = p; 1 <= j; j-- )
    {
      if ( jpvt[j-1] < 0 )
      {
        jpvt[j-1] = -jpvt[j-1];

        if ( j != pu )
        {
          dswap ( n, a+0+(pu-1)*lda, 1, a+0+(j-1)*lda, 1 );
          jp = jpvt[pu-1];
          jpvt[pu-1] = jpvt[j-1];
          jpvt[j-1] = jp;
        }
        pu = pu - 1;
      }
    }
  }
/*
  Compute the norms of the free columns.
*/
  for ( j = pl; j <= pu; j++ )
  {
    qraux[j-1] = dnrm2 ( n, a+0+(j-1)*lda, 1 );
  }

  for ( j = pl; j <= pu; j++ )
  {
    work[j-1] = qraux[j-1];
  }
/*
  Perform the Householder reduction of A.
*/
  lup = i4_min ( n, p );

  for ( l = 1; l <= lup; l++ )
  {
/*
  Bring the column of largest norm into the pivot position.
*/
    if ( pl <= l && l < pu )
    {
      maxnrm = 0.0;
      maxj = l;
      for ( j = l; j <= pu; j++ )
      {
        if ( maxnrm < qraux[j-1] )
        {
          maxnrm = qraux[j-1];
          maxj = j;
        }
      }

      if ( maxj != l )
      {
        dswap ( n, a+0+(l-1)*lda, 1, a+0+(maxj-1)*lda, 1 );
        qraux[maxj-1] = qraux[l-1];
        work[maxj-1] = work[l-1];
        jp = jpvt[maxj-1];
        jpvt[maxj-1] = jpvt[l-1];
        jpvt[l-1] = jp;
      }
    }
/*
  Compute the Householder transformation for column L.
*/
    qraux[l-1] = 0.0;

    if ( l != n )
    {
      nrmxl = dnrm2 ( n-l+1, a+l-1+(l-1)*lda, 1 );

      if ( nrmxl != 0.0 )
      {
        if ( a[l-1+(l-1)*lda] != 0.0 )
        {
          nrmxl = nrmxl * r8_sign ( a[l-1+(l-1)*lda] );
        }

        dscal ( n-l+1, 1.0 / nrmxl, a+l-1+(l-1)*lda, 1 );
        a[l-1+(l-1)*lda] = 1.0 + a[l-1+(l-1)*lda];
/*
  Apply the transformation to the remaining columns, updating the norms.
*/
        for ( j = l + 1; j <= p; j++ )
        {
          t = -ddot ( n-l+1, a+l-1+(l-1)*lda, 1, a+l-1+(j-1)*lda, 1 ) 
            / a[l-1+(l-1)*lda];
          daxpy ( n-l+1, t, a+l-1+(l-1)*lda, 1, a+l-1+(j-1)*lda, 1 );

          if ( pl <= j && j <= pu )
          {
            if ( qraux[j-1] != 0.0 )
            {
              tt = 1.0 - pow ( r8_abs ( a[l-1+(j-1)*lda] ) / qraux[j-1], 2 );
              tt = r8_max ( tt, 0.0 );
              t = tt;
              tt = 1.0 + 0.05 * tt * pow ( qraux[j-1] / work[j-1], 2 );

              if ( tt != 1.0 )
              {
                qraux[j-1] = qraux[j-1] * sqrt ( t );
              }
              else
              {
                qraux[j-1] = dnrm2 ( n-l, a+l+(j-1)*lda, 1 );
                work[j-1] = qraux[j-1];
              }
            }
          }
        }
/*
  Save the transformation.
*/
        qraux[l-1] = a[l-1+(l-1)*lda];
        a[l-1+(l-1)*lda] = -nrmxl;
      }
    }
  }
  return;
}
Exemple #2
0
inline static void vecswap(double* x, double* y, const int n) {
  /* swap x and y */
  dswap(n, x, 1, y, 1);
}
Exemple #3
0
/*
** Uses G-drive non-anti-aliased method to draw triangle.  Set only for now.
*/
static void render_triangle_2(WILLUSBITMAP *bmp,TRIANGLE2D *srctri,
                              RENDER_COLOR *color)

    {
    double  x1,y1,x2,y2,x3,y3,ylast;
    int    *pattern;
    int     def[2] = {1,0xffff};
    double  px1,py1,px2,py2,px3,py3;
    double  ldy,rdy;
    double  x1clip,x2clip,y1clip,y2clip;
    double  ldx,rdx;
    int     lx,rx,y,yi,yf,yinc;
/*
printf("@rt2 (%6.4f,%6.4f)-(%6.4f,%6.4f)-(%6.4f,%6.4f)\n",
srctri->p[0].x,srctri->p[0].y,
srctri->p[1].x,srctri->p[1].y,
srctri->p[2].x,srctri->p[2].y);
*/

    pattern = NULL;
    x1 = srctri->p[0].x;
    y1 = srctri->p[0].y;
    x2 = srctri->p[1].x;
    y2 = srctri->p[1].y;
    x3 = srctri->p[2].x;
    y3 = srctri->p[2].y;
    x1clip=0;
    x2clip=bmp->width;
    y1clip=0;
    y2clip=bmp->height;
/*
    px1=render_col(bmp,x1);
    py1=render_row(bmp,y1);
    px2=render_col(bmp,x2);
    py2=render_row(bmp,y2);
    px3=render_col(bmp,x3);
    py3=render_row(bmp,y3);
*/
    px1=x1*bmp->width;
    py1=y1*bmp->height;
    px2=x2*bmp->width;
    py2=y2*bmp->height;
    px3=x3*bmp->width;
    py3=y3*bmp->height;
    if (py1>py2)
        dswap(px1,py1,px2,py2);
    if (py2>py3)
        dswap(px2,py2,px3,py3);
    if (py1>py2)
        dswap(px1,py1,px2,py2);
    if (py1>y2clip || py3<y1clip)
        return;
    if (pattern==NULL)
        pattern=def;
    if (py1==py2 && py2==py3)
        {
        lx = min3(px1,px2,px3);
        rx = max3(px1,px2,px3);
        if (lx>x2clip || rx<x1clip)
            return;
        if (lx<x1clip)
            lx=x1clip;
        if (rx>x2clip)
            rx=x2clip;
        }
    if (py1==py3)
        x1=(double)(px1+px3)/2.;
    else
        x1=px1+(double)(px3-px1)*(double)(py2-py1)/(double)(py3-py1);
    yinc=1;
// printf("py1=%7.2f, py2=%7.2f\n",py1,py2);
    if (py2>=y1clip && py2!=py1)
        {
        yi = floor((py1>y1clip ? py1 : y1clip)+.5);
        yf = floor((py2<y2clip ? py2 : y2clip)-.5);
// printf("yi=%d, yf=%d\n",yi,yf);
        if (x1>(double)px2)
            {
            ldx=px2-px1;
            rdx=px3-px1;
            ldy=py2-py1;
            rdy=py3-py1;
            }
        else
            {
            ldx=px3-px1;
            rdx=px2-px1;
            ldy=py3-py1;
            rdy=py2-py1;
            }
        for (y=yi;y<=yf;y+=yinc)
            {
            lx=floor((px1+ldx*(y+.5-py1)/ldy)+.5);
            rx=floor((px1+rdx*(y+.5-py1)/rdy)-.5);
// printf("lx,rx[%d] = %d, %d\n",y,lx,rx);
            if (lx>rx)
                continue;
            if (lx>x2clip || rx<x1clip)
                continue;
            if (lx<x1clip)
                lx=x1clip;
            if (rx>x2clip)
                rx=x2clip;
            if (lx>rx)
                continue;
            render_horizontal_line(bmp,lx,y,rx,color);
                /*
                if ((status=hlinepat(lx,y,rx,pen_color,pattern[y%pattern[0]+1]))!=NO_ERROR)
                    return(status);
                */
            }
        }
    ylast=py2;
// printf("ylast=%7.2f, py3=%7.2f\n",ylast,py3);
    if (ylast<=y2clip && py2!=py3)
        {
        yi = floor((ylast>y1clip ? ylast : y1clip)+.5);
        yf = floor((py3<y2clip ? py3 : y2clip)-.5);
// printf("yi=%d, yf=%d\n",yi,yf);
        if (x1>px2)
            {
            ldx=px2-px3;
            rdx=px1-px3;
            ldy=py3-py2;
            rdy=py3-py1;
            }
        else
            {
            ldx=px1-px3;
            rdx=px2-px3;
            ldy=py3-py1;
            rdy=py3-py2;
            }
// printf("px3=%g, ldx=%g, rdx=%g, ldy=%g, rdy=%g\n",px3,ldx,rdx,ldy,rdy);
        for (y=yi;y<=yf;y+=yinc)
            {
            lx=floor((px3+ldx*(py3-(y+.5))/ldy)+.5);
            rx=floor((px3+rdx*(py3-(y+.5))/rdy)-.5);
// printf("lx,rxdp[%d] = %15.10f, %15.10f\n",y,px3+ldx*(py3-(y+.5))/ldy,px3+rdx*(py3-(y+.5))/rdy);
// printf("lx,rx[%d] = %d, %d\n",y,lx,rx);
            if (lx>x2clip || rx<x1clip)
                continue;
            if (lx<x1clip)
                lx=x1clip;
            if (rx>x2clip)
                rx=x2clip;
            if (lx>rx)
                continue;
            render_horizontal_line(bmp,lx,y,rx,color);
            /*
            if ((status=hlinepat(lx,y,rx,pen_color,pattern[y%pattern[0]+1]))!=NO_ERROR)
                return(status);
            */
            }
        }
    }
void LUdswap( ptrdiff_t n, double *dx, ptrdiff_t incx, double *dy, ptrdiff_t incy )
{
  dx++;
  dy++;
  dswap( &n, dx, &incx, dy, &incy );
}