Exemple #1
0
int main(int argc, char **argv)
{
    int             bits_per_pixel = 8, cmsize, i, j, k,
                    cmap_index, chunk_size = 32, nchunks = 16;
    unsigned char * scan_line;
    uint16          *red, *green, *blue;
    TIFF *          tif;

    programName = argv[0];

    if (argc != 4)
        Usage();

    if (!strcmp(argv[1], "-depth"))
         bits_per_pixel = atoi(argv[2]);
    else
         Usage();

    switch (bits_per_pixel) {
        case 8:
            nchunks = 16;
            chunk_size = 32;
            break;
        case 4:
            nchunks = 4;
            chunk_size = 128;
            break;
        case 2:
            nchunks = 2;
            chunk_size = 256;
            break;
	case 1:
	    nchunks = 2;
	    chunk_size = 256;
	    break;
        default:
            Usage();
    }

    if (bits_per_pixel != 1) {
	cmsize = nchunks * nchunks;
    } else {
	cmsize = 2;
    }
    red = (uint16 *) malloc(cmsize * sizeof(uint16));
    green = (uint16 *) malloc(cmsize * sizeof(uint16));
    blue = (uint16 *) malloc(cmsize * sizeof(uint16));

    switch (bits_per_pixel) {
    case 8:
        for (i = 0; i < cmsize; i++) {
            if (i < 32)
                red[i] = 0;
            else if (i < 64)
                red[i] = SCALE(36);
            else if (i < 96)
                red[i] = SCALE(73);
            else if (i < 128)
                red[i] = SCALE(109);
            else if (i < 160)
                red[i] = SCALE(146);
            else if (i < 192)
                red[i] = SCALE(182);
            else if (i < 224)
                red[i] = SCALE(219);
            else if (i < 256)
                red[i] = SCALE(255);

            if ((i % 32) < 4)
                green[i] = 0;
            else if (i < 8)
                green[i] = SCALE(36);
            else if ((i % 32) < 12)
                green[i] = SCALE(73);
            else if ((i % 32) < 16)
                green[i] = SCALE(109);
            else if ((i % 32) < 20)
                green[i] = SCALE(146);
            else if ((i % 32) < 24)
                green[i] = SCALE(182);
            else if ((i % 32) < 28)
                green[i] = SCALE(219);
            else if ((i % 32) < 32)
                green[i] = SCALE(255);

            if ((i % 4) == 0)
                blue[i] = SCALE(0);
            else if ((i % 4) == 1)
                blue[i] = SCALE(85);
            else if ((i % 4) == 2)
                blue[i] = SCALE(170);
            else if ((i % 4) == 3)
                blue[i] = SCALE(255);
        }
        break;
    case 4:
        red[0] = SCALE(255);
        green[0] = 0;
        blue[0] = 0;

        red[1] = 0;
        green[1] = SCALE(255);
        blue[1] = 0;

        red[2] = 0;
        green[2] = 0;
        blue[2] = SCALE(255);

        red[3] = SCALE(255);
        green[3] = SCALE(255);
        blue[3] = SCALE(255);

        red[4] = 0;
        green[4] = SCALE(255);
        blue[4] = SCALE(255);

        red[5] = SCALE(255);
        green[5] = 0;
        blue[5] = SCALE(255);

        red[6] = SCALE(255);
        green[6] = SCALE(255);
        blue[6] = 0;

        red[7] = 0;
        green[7] = 0;
        blue[7] = 0;

        red[8] = SCALE(176);
        green[8] = SCALE(224);
        blue[8] = SCALE(230);
        red[9] = SCALE(100);
        green[9] = SCALE(149);
        blue[9] = SCALE(237);
        red[10] = SCALE(46);
        green[10] = SCALE(139);
        blue[10] = SCALE(87);
        red[11] = SCALE(160);
        green[11] = SCALE(82);
        blue[11] = SCALE(45);
        red[12] = SCALE(238);
        green[12] = SCALE(130);
        blue[12] = SCALE(238);
        red[13] = SCALE(176);
        green[13] = SCALE(48);
        blue[13] = SCALE(96);
        red[14] = SCALE(50);
        green[14] = SCALE(205);
        blue[14] = SCALE(50);
        red[15] = SCALE(240);
        green[15] = SCALE(152);
        blue[15] = SCALE(35);
        break;
    case 2:
        red[0] = SCALE(255);
        green[0] = 0;
        blue[0] = 0;

        red[1] = 0;
        green[1] = SCALE(255);
        blue[1] = 0;

        red[2] = 0;
        green[2] = 0;
        blue[2] = SCALE(255);
        red[3] = SCALE(255);
        green[3] = SCALE(255);
        blue[3] = SCALE(255);
        break;
    case 1:
        red[0] = 0;
        green[0] = 0;
        blue[0] = 0;

        red[1] = SCALE(255);
        green[1] = SCALE(255);
        blue[1] = SCALE(255);
        break;
    }

    if ((tif = TIFFOpen(argv[3], "w")) == NULL) {
        fprintf(stderr, "can't open %s as a TIFF file\n", argv[3]);
        return 0;
    }

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_pixel);
    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
    TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);

    scan_line = (unsigned char *) malloc(WIDTH / (8 / bits_per_pixel));

    for (i = 0; i < HEIGHT; i++) {
        for (j = 0, k = 0; j < WIDTH;) {
            cmap_index = (j / chunk_size) + ((i / chunk_size) * nchunks);

            switch (bits_per_pixel) {
            case 8:
                scan_line[k++] = cmap_index;
                j++;
                break;
            case 4:
                scan_line[k++] = (cmap_index << 4) + cmap_index;
                j += 2;
                break;
            case 2:
                scan_line[k++] = (cmap_index << 6) + (cmap_index << 4)
                    + (cmap_index << 2) + cmap_index;
                j += 4;
                break;
	    case 1:
		scan_line[k++] =
			((j / chunk_size) == (i / chunk_size)) ? 0x00 : 0xff;
		j += 8;
		break;
            }
        }
        TIFFWriteScanline(tif, scan_line, i, 0);
    }

    free(scan_line);
    TIFFClose(tif);
    return 0;
}
Exemple #2
0
static void plot_profile(struct dive *dive, cairo_t *cr,
	double topx, double topy, double maxx, double maxy)
{
	double scalex, scaley;
	int begins, sec, depth;
	int i, samples;
	struct sample *sample;
	int maxtime, maxdepth;

	samples = dive->samples;
	if (!samples)
		return;

	cairo_set_line_width(cr, 2);

	/* Get plot scaling limits */
	maxtime = round_seconds_up(dive->duration.seconds);
	maxdepth = round_feet_up(to_feet(dive->maxdepth));

	/* Time markers: every 5 min */
	scalex = maxtime;
	scaley = 1.0;
	for (i = 5*60; i < maxtime; i += 5*60) {
		cairo_move_to(cr, SCALE(i, 0));
		cairo_line_to(cr, SCALE(i, 1));
	}

	/* Depth markers: every 15 ft */
	scalex = 1.0;
	scaley = maxdepth;
	cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
	for (i = 15; i < maxdepth; i += 15) {
		cairo_move_to(cr, SCALE(0, i));
		cairo_line_to(cr, SCALE(1, i));
	}
	cairo_stroke(cr);

	/* Show mean depth */
	cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.40);
	cairo_move_to(cr, SCALE(0, to_feet(dive->meandepth)));
	cairo_line_to(cr, SCALE(1, to_feet(dive->meandepth)));
	cairo_stroke(cr);

	scalex = maxtime;

	sample = dive->sample;
	cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.80);
	begins = sample->time.seconds;
	cairo_move_to(cr, SCALE(sample->time.seconds, to_feet(sample->depth)));
	for (i = 1; i < dive->samples; i++) {
		sample++;
		sec = sample->time.seconds;
		depth = to_feet(sample->depth);
		cairo_line_to(cr, SCALE(sec, depth));
	}
	scaley = 1.0;
	cairo_line_to(cr, SCALE(sec, 0));
	cairo_line_to(cr, SCALE(begins, 0));
	cairo_close_path(cr);
	cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.20);
	cairo_fill_preserve(cr);
	cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.80);
	cairo_stroke(cr);
}
Exemple #3
0
/* Subroutine */ int zgebal_(char *job, integer *n, doublecomplex *a, integer 
	*lda, integer *ilo, integer *ihi, doublereal *scale, integer *info)
{
/*  -- LAPACK routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       September 30, 1994   


    Purpose   
    =======   

    ZGEBAL balances a general complex matrix A.  This involves, first,   
    permuting A by a similarity transformation to isolate eigenvalues   
    in the first 1 to ILO-1 and last IHI+1 to N elements on the   
    diagonal; and second, applying a diagonal similarity transformation   
    to rows and columns ILO to IHI to make the rows and columns as   
    close in norm as possible.  Both steps are optional.   

    Balancing may reduce the 1-norm of the matrix, and improve the   
    accuracy of the computed eigenvalues and/or eigenvectors.   

    Arguments   
    =========   

    JOB     (input) CHARACTER*1   
            Specifies the operations to be performed on A:   
            = 'N':  none:  simply set ILO = 1, IHI = N, SCALE(I) = 1.0   
                    for i = 1,...,N;   
            = 'P':  permute only;   
            = 'S':  scale only;   
            = 'B':  both permute and scale.   

    N       (input) INTEGER   
            The order of the matrix A.  N >= 0.   

    A       (input/output) COMPLEX*16 array, dimension (LDA,N)   
            On entry, the input matrix A.   
            On exit,  A is overwritten by the balanced matrix.   
            If JOB = 'N', A is not referenced.   
            See Further Details.   

    LDA     (input) INTEGER   
            The leading dimension of the array A.  LDA >= max(1,N).   

    ILO     (output) INTEGER   
    IHI     (output) INTEGER   
            ILO and IHI are set to integers such that on exit   
            A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.   
            If JOB = 'N' or 'S', ILO = 1 and IHI = N.   

    SCALE   (output) DOUBLE PRECISION array, dimension (N)   
            Details of the permutations and scaling factors applied to   
            A.  If P(j) is the index of the row and column interchanged   
            with row and column j and D(j) is the scaling factor   
            applied to row and column j, then   
            SCALE(j) = P(j)    for j = 1,...,ILO-1   
                     = D(j)    for j = ILO,...,IHI   
                     = P(j)    for j = IHI+1,...,N.   
            The order in which the interchanges are made is N to IHI+1,   
            then 1 to ILO-1.   

    INFO    (output) INTEGER   
            = 0:  successful exit.   
            < 0:  if INFO = -i, the i-th argument had an illegal value.   

    Further Details   
    ===============   

    The permutations consist of row and column interchanges which put   
    the matrix in the form   

               ( T1   X   Y  )   
       P A P = (  0   B   Z  )   
               (  0   0   T2 )   

    where T1 and T2 are upper triangular matrices whose eigenvalues lie   
    along the diagonal.  The column indices ILO and IHI mark the starting 
  
    and ending columns of the submatrix B. Balancing consists of applying 
  
    a diagonal similarity transformation inv(D) * B * D to make the   
    1-norms of each row of B and its corresponding column nearly equal.   
    The output matrix is   

       ( T1     X*D          Y    )   
       (  0  inv(D)*B*D  inv(D)*Z ).   
       (  0      0           T2   )   

    Information about the permutations P and the diagonal matrix D is   
    returned in the vector SCALE.   

    This subroutine is based on the EISPACK routine CBAL.   

    ===================================================================== 
  


       Test the input parameters   

    
   Parameter adjustments   
       Function Body */
    /* Table of constant values */
    static integer c__1 = 1;
    
    /* System generated locals */
    integer a_dim1, a_offset, i__1, i__2, i__3;
    doublereal d__1, d__2;
    /* Builtin functions */
    double d_imag(doublecomplex *), z_abs(doublecomplex *);
    /* Local variables */
    static integer iexc;
    static doublereal c, f, g;
    static integer i, j, k, l, m;
    static doublereal r, s;
    extern logical lsame_(char *, char *);
    extern /* Subroutine */ int zswap_(integer *, doublecomplex *, integer *, 
	    doublecomplex *, integer *);
    static doublereal sfmin1, sfmin2, sfmax1, sfmax2, ca, ra;
    extern doublereal dlamch_(char *);
    extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_(
	    integer *, doublereal *, doublecomplex *, integer *);
    extern integer izamax_(integer *, doublecomplex *, integer *);
    static logical noconv;
    static integer ica, ira;



#define SCALE(I) scale[(I)-1]

#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)]

    *info = 0;
    if (! lsame_(job, "N") && ! lsame_(job, "P") && ! lsame_(
	    job, "S") && ! lsame_(job, "B")) {
	*info = -1;
    } else if (*n < 0) {
	*info = -2;
    } else if (*lda < max(1,*n)) {
	*info = -4;
    }
    if (*info != 0) {
	i__1 = -(*info);
	xerbla_("ZGEBAL", &i__1);
	return 0;
    }

    k = 1;
    l = *n;

    if (*n == 0) {
	goto L210;
    }

    if (lsame_(job, "N")) {
	i__1 = *n;
	for (i = 1; i <= *n; ++i) {
	    SCALE(i) = 1.;
/* L10: */
	}
	goto L210;
    }

    if (lsame_(job, "S")) {
	goto L120;
    }

/*     Permutation to isolate eigenvalues if possible */

    goto L50;

/*     Row and column exchange. */

L20:
    SCALE(m) = (doublereal) j;
    if (j == m) {
	goto L30;
    }

    zswap_(&l, &A(1,j), &c__1, &A(1,m), &c__1);
    i__1 = *n - k + 1;
    zswap_(&i__1, &A(j,k), lda, &A(m,k), lda);

L30:
    switch (iexc) {
	case 1:  goto L40;
	case 2:  goto L80;
    }

/*     Search for rows isolating an eigenvalue and push them down. */

L40:
    if (l == 1) {
	goto L210;
    }
    --l;

L50:
    for (j = l; j >= 1; --j) {

	i__1 = l;
	for (i = 1; i <= l; ++i) {
	    if (i == j) {
		goto L60;
	    }
	    i__2 = j + i * a_dim1;
	    if (A(j,i).r != 0. || d_imag(&A(j,i)) != 0.) {
		goto L70;
	    }
L60:
	    ;
	}

	m = l;
	iexc = 1;
	goto L20;
L70:
	;
    }

    goto L90;

/*     Search for columns isolating an eigenvalue and push them left. */

L80:
    ++k;

L90:
    i__1 = l;
    for (j = k; j <= l; ++j) {

	i__2 = l;
	for (i = k; i <= l; ++i) {
	    if (i == j) {
		goto L100;
	    }
	    i__3 = i + j * a_dim1;
	    if (A(i,j).r != 0. || d_imag(&A(i,j)) != 0.) {
		goto L110;
	    }
L100:
	    ;
	}

	m = k;
	iexc = 2;
	goto L20;
L110:
	;
    }

L120:
    i__1 = l;
    for (i = k; i <= l; ++i) {
	SCALE(i) = 1.;
/* L130: */
    }

    if (lsame_(job, "P")) {
	goto L210;
    }

/*     Balance the submatrix in rows K to L.   

       Iterative loop for norm reduction */

    sfmin1 = dlamch_("S") / dlamch_("P");
    sfmax1 = 1. / sfmin1;
    sfmin2 = sfmin1 * 10.;
    sfmax2 = 1. / sfmin2;
L140:
    noconv = FALSE_;

    i__1 = l;
    for (i = k; i <= l; ++i) {
	c = 0.;
	r = 0.;

	i__2 = l;
	for (j = k; j <= l; ++j) {
	    if (j == i) {
		goto L150;
	    }
	    i__3 = j + i * a_dim1;
	    c += (d__1 = A(j,i).r, abs(d__1)) + (d__2 = d_imag(&A(j,i)), abs(d__2));
	    i__3 = i + j * a_dim1;
	    r += (d__1 = A(i,j).r, abs(d__1)) + (d__2 = d_imag(&A(i,j)), abs(d__2));
L150:
	    ;
	}
	ica = izamax_(&l, &A(1,i), &c__1);
	ca = z_abs(&A(ica,i));
	i__2 = *n - k + 1;
	ira = izamax_(&i__2, &A(i,k), lda);
	ra = z_abs(&A(i,ira+k-1));

/*        Guard against zero C or R due to underflow. */

	if (c == 0. || r == 0.) {
	    goto L200;
	}
	g = r / 10.;
	f = 1.;
	s = c + r;
L160:
/* Computing MAX */
	d__1 = max(f,c);
/* Computing MIN */
	d__2 = min(r,g);
	if (c >= g || max(d__1,ca) >= sfmax2 || min(d__2,ra) <= sfmin2) {
	    goto L170;
	}
	f *= 10.;
	c *= 10.;
	ca *= 10.;
	r /= 10.;
	g /= 10.;
	ra /= 10.;
	goto L160;

L170:
	g = c / 10.;
L180:
/* Computing MIN */
	d__1 = min(f,c), d__1 = min(d__1,g);
	if (g < r || max(r,ra) >= sfmax2 || min(d__1,ca) <= sfmin2) {
	    goto L190;
	}
	f /= 10.;
	c /= 10.;
	g /= 10.;
	ca /= 10.;
	r *= 10.;
	ra *= 10.;
	goto L180;

/*        Now balance. */

L190:
	if (c + r >= s * .95) {
	    goto L200;
	}
	if (f < 1. && SCALE(i) < 1.) {
	    if (f * SCALE(i) <= sfmin1) {
		goto L200;
	    }
	}
	if (f > 1. && SCALE(i) > 1.) {
	    if (SCALE(i) >= sfmax1 / f) {
		goto L200;
	    }
	}
	g = 1. / f;
	SCALE(i) *= f;
	noconv = TRUE_;

	i__2 = *n - k + 1;
	zdscal_(&i__2, &g, &A(i,k), lda);
	zdscal_(&l, &f, &A(1,i), &c__1);

L200:
	;
    }

    if (noconv) {
	goto L140;
    }

L210:
    *ilo = k;
    *ihi = l;

    return 0;

/*     End of ZGEBAL */

} /* zgebal_ */
Exemple #4
0
int ICODE_ATTR_DEMAC decode_chunk(struct ape_ctx_t* ape_ctx,
                                  unsigned char* inbuffer, int* firstbyte,
                                  int* bytesconsumed,
                                  int32_t* decoded0, int32_t* decoded1,
                                  int count)
{
    int32_t left, right;
#ifdef ROCKBOX
    int scale = (APE_OUTPUT_DEPTH - ape_ctx->bps);
    #define SCALE(x) ((x) << scale)
#else
    #define SCALE(x) (x)
#endif
         
    if ((ape_ctx->channels==1) || ((ape_ctx->frameflags
        & (APE_FRAMECODE_PSEUDO_STEREO|APE_FRAMECODE_STEREO_SILENCE))
        == APE_FRAMECODE_PSEUDO_STEREO)) {

        entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed,
                       decoded0, NULL, count);

        if (ape_ctx->frameflags & APE_FRAMECODE_MONO_SILENCE) {
            /* We are pure silence, so we're done. */
            return 0;
        }

        switch (ape_ctx->compressiontype)
        {
            case 2000:
                apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
                break;
    
            case 3000:
                apply_filter_64_11(ape_ctx->fileversion,0,decoded0,count);
                break;
    
            case 4000:
                apply_filter_32_10(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
                break;
    
            case 5000:
                apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_1280_15(ape_ctx->fileversion,0,decoded0,count);
        }

        /* Now apply the predictor decoding */
        predictor_decode_mono(&ape_ctx->predictor,decoded0,count);

        if (ape_ctx->channels==2) {
            /* Pseudo-stereo - copy left channel to right channel */
            while (count--)
            {
                left = *decoded0;
                *(decoded1++) = *(decoded0++) = SCALE(left);
            }
        }
#ifdef ROCKBOX
         else {
            /* Scale to output depth */
            while (count--)
            {
                left = *decoded0;
                *(decoded0++) = SCALE(left);
            }
        }
#endif
    } else { /* Stereo */
        entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed,
                       decoded0, decoded1, count);

        if ((ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE)
            == APE_FRAMECODE_STEREO_SILENCE) {
            /* We are pure silence, so we're done. */
            return 0;
        }

        /* Apply filters - compression type 1000 doesn't have any */
        switch (ape_ctx->compressiontype)
        {
            case 2000:
                apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_16_11(ape_ctx->fileversion,1,decoded1,count);
                break;
    
            case 3000:
                apply_filter_64_11(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_64_11(ape_ctx->fileversion,1,decoded1,count);
                break;
    
            case 4000:
                apply_filter_32_10(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_32_10(ape_ctx->fileversion,1,decoded1,count);
                apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_256_13(ape_ctx->fileversion,1,decoded1,count);
                break;
    
            case 5000:
                apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_16_11(ape_ctx->fileversion,1,decoded1,count);
                apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_256_13(ape_ctx->fileversion,1,decoded1,count);
                apply_filter_1280_15(ape_ctx->fileversion,0,decoded0,count);
                apply_filter_1280_15(ape_ctx->fileversion,1,decoded1,count);
        }

        /* Now apply the predictor decoding */
        predictor_decode_stereo(&ape_ctx->predictor,decoded0,decoded1,count);

        /* Decorrelate and scale to output depth */
        while (count--)
        {
            left = *decoded1 - (*decoded0 / 2);
            right = left + *decoded0;

            *(decoded0++) = SCALE(left);
            *(decoded1++) = SCALE(right);
        }
    }
    return 0;
}
Exemple #5
0
/* Subroutine */ int zgeevx_(char *balanc, char *jobvl, char *jobvr, char *
                             sense, integer *n, doublecomplex *a, integer *lda, doublecomplex *w,
                             doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *ldvr,
                             integer *ilo, integer *ihi, doublereal *scale, doublereal *abnrm,
                             doublereal *rconde, doublereal *rcondv, doublecomplex *work, integer *
                             lwork, doublereal *rwork, integer *info)
{
    /*  -- LAPACK driver routine (version 2.0) --
           Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
           Courant Institute, Argonne National Lab, and Rice University
           September 30, 1994


        Purpose
        =======

        ZGEEVX computes for an N-by-N complex nonsymmetric matrix A, the
        eigenvalues and, optionally, the left and/or right eigenvectors.

        Optionally also, it computes a balancing transformation to improve
        the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
        SCALE, and ABNRM), reciprocal condition numbers for the eigenvalues
        (RCONDE), and reciprocal condition numbers for the right
        eigenvectors (RCONDV).

        The right eigenvector v(j) of A satisfies
                         A * v(j) = lambda(j) * v(j)
        where lambda(j) is its eigenvalue.
        The left eigenvector u(j) of A satisfies
                      u(j)**H * A = lambda(j) * u(j)**H
        where u(j)**H denotes the conjugate transpose of u(j).

        The computed eigenvectors are normalized to have Euclidean norm
        equal to 1 and largest component real.

        Balancing a matrix means permuting the rows and columns to make it
        more nearly upper triangular, and applying a diagonal similarity
        transformation D * A * D**(-1), where D is a diagonal matrix, to
        make its rows and columns closer in norm and the condition numbers
        of its eigenvalues and eigenvectors smaller.  The computed
        reciprocal condition numbers correspond to the balanced matrix.
        Permuting rows and columns will not change the condition numbers
        (in exact arithmetic) but diagonal scaling will.  For further
        explanation of balancing, see section 4.10.2 of the LAPACK
        Users' Guide.

        Arguments
        =========

        BALANC  (input) CHARACTER*1
                Indicates how the input matrix should be diagonally scaled
                and/or permuted to improve the conditioning of its
                eigenvalues.
                = 'N': Do not diagonally scale or permute;
                = 'P': Perform permutations to make the matrix more nearly
                       upper triangular. Do not diagonally scale;
                = 'S': Diagonally scale the matrix, ie. replace A by
                       D*A*D**(-1), where D is a diagonal matrix chosen
                       to make the rows and columns of A more equal in
                       norm. Do not permute;
                = 'B': Both diagonally scale and permute A.

                Computed reciprocal condition numbers will be for the matrix

                after balancing and/or permuting. Permuting does not change
                condition numbers (in exact arithmetic), but balancing does.


        JOBVL   (input) CHARACTER*1
                = 'N': left eigenvectors of A are not computed;
                = 'V': left eigenvectors of A are computed.
                If SENSE = 'E' or 'B', JOBVL must = 'V'.

        JOBVR   (input) CHARACTER*1
                = 'N': right eigenvectors of A are not computed;
                = 'V': right eigenvectors of A are computed.
                If SENSE = 'E' or 'B', JOBVR must = 'V'.

        SENSE   (input) CHARACTER*1
                Determines which reciprocal condition numbers are computed.
                = 'N': None are computed;
                = 'E': Computed for eigenvalues only;
                = 'V': Computed for right eigenvectors only;
                = 'B': Computed for eigenvalues and right eigenvectors.

                If SENSE = 'E' or 'B', both left and right eigenvectors
                must also be computed (JOBVL = 'V' and JOBVR = 'V').

        N       (input) INTEGER
                The order of the matrix A. N >= 0.

        A       (input/output) COMPLEX*16 array, dimension (LDA,N)
                On entry, the N-by-N matrix A.
                On exit, A has been overwritten.  If JOBVL = 'V' or
                JOBVR = 'V', A contains the Schur form of the balanced
                version of the matrix A.

        LDA     (input) INTEGER
                The leading dimension of the array A.  LDA >= max(1,N).

        W       (output) COMPLEX*16 array, dimension (N)
                W contains the computed eigenvalues.

        VL      (output) COMPLEX*16 array, dimension (LDVL,N)
                If JOBVL = 'V', the left eigenvectors u(j) are stored one
                after another in the columns of VL, in the same order
                as their eigenvalues.
                If JOBVL = 'N', VL is not referenced.
                u(j) = VL(:,j), the j-th column of VL.

        LDVL    (input) INTEGER
                The leading dimension of the array VL.  LDVL >= 1; if
                JOBVL = 'V', LDVL >= N.

        VR      (output) COMPLEX*16 array, dimension (LDVR,N)
                If JOBVR = 'V', the right eigenvectors v(j) are stored one
                after another in the columns of VR, in the same order
                as their eigenvalues.
                If JOBVR = 'N', VR is not referenced.
                v(j) = VR(:,j), the j-th column of VR.

        LDVR    (input) INTEGER
                The leading dimension of the array VR.  LDVR >= 1; if
                JOBVR = 'V', LDVR >= N.

        ILO,IHI (output) INTEGER
                ILO and IHI are integer values determined when A was
                balanced.  The balanced A(i,j) = 0 if I > J and
                J = 1,...,ILO-1 or I = IHI+1,...,N.

        SCALE   (output) DOUBLE PRECISION array, dimension (N)
                Details of the permutations and scaling factors applied
                when balancing A.  If P(j) is the index of the row and column

                interchanged with row and column j, and D(j) is the scaling
                factor applied to row and column j, then
                SCALE(J) = P(J),    for J = 1,...,ILO-1
                         = D(J),    for J = ILO,...,IHI
                         = P(J)     for J = IHI+1,...,N.
                The order in which the interchanges are made is N to IHI+1,
                then 1 to ILO-1.

        ABNRM   (output) DOUBLE PRECISION
                The one-norm of the balanced matrix (the maximum
                of the sum of absolute values of elements of any column).

        RCONDE  (output) DOUBLE PRECISION array, dimension (N)
                RCONDE(j) is the reciprocal condition number of the j-th
                eigenvalue.

        RCONDV  (output) DOUBLE PRECISION array, dimension (N)
                RCONDV(j) is the reciprocal condition number of the j-th
                right eigenvector.

        WORK    (workspace/output) COMPLEX*16 array, dimension (LWORK)
                On exit, if INFO = 0, WORK(1) returns the optimal LWORK.

        LWORK   (input) INTEGER
                The dimension of the array WORK.  If SENSE = 'N' or 'E',
                LWORK >= max(1,2*N), and if SENSE = 'V' or 'B',
                LWORK >= N*N+2*N.
                For good performance, LWORK must generally be larger.

        RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)

        INFO    (output) INTEGER
                = 0:  successful exit
                < 0:  if INFO = -i, the i-th argument had an illegal value.
                > 0:  if INFO = i, the QR algorithm failed to compute all the

                      eigenvalues, and no eigenvectors or condition numbers
                      have been computed; elements 1:ILO-1 and i+1:N of W
                      contain eigenvalues which have converged.

        =====================================================================



           Test the input arguments


       Parameter adjustments
           Function Body */
    /* Table of constant values */
    static integer c__1 = 1;
    static integer c__0 = 0;
    static integer c__8 = 8;
    static integer c_n1 = -1;
    static integer c__4 = 4;

    /* System generated locals */
    integer a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1,
            i__2, i__3, i__4;
    doublereal d__1, d__2;
    doublecomplex z__1, z__2;
    /* Builtin functions */
    double sqrt(doublereal), d_imag(doublecomplex *);
    void d_cnjg(doublecomplex *, doublecomplex *);
    /* Local variables */
    static char side[1];
    static integer maxb;
    static doublereal anrm;
    static integer ierr, itau, iwrk, nout, i, k, icond;
    extern logical lsame_(char *, char *);
    extern /* Subroutine */ int zscal_(integer *, doublecomplex *,
                                       doublecomplex *, integer *), dlabad_(doublereal *, doublereal *);
    extern doublereal dznrm2_(integer *, doublecomplex *, integer *);
    static logical scalea;
    extern doublereal dlamch_(char *);
    static doublereal cscale;
    extern /* Subroutine */ int dlascl_(char *, integer *, integer *,
                                        doublereal *, doublereal *, integer *, integer *, doublereal *,
                                        integer *, integer *), zgebak_(char *, char *, integer *,
                                                integer *, integer *, doublereal *, integer *, doublecomplex *,
                                                integer *, integer *), zgebal_(char *, integer *,
                                                        doublecomplex *, integer *, integer *, integer *, doublereal *,
                                                        integer *);
    extern integer idamax_(integer *, doublereal *, integer *);
    extern /* Subroutine */ int xerbla_(char *, integer *);
    extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
                           integer *, integer *, ftnlen, ftnlen);
    static logical select[1];
    extern /* Subroutine */ int zdscal_(integer *, doublereal *,
                                        doublecomplex *, integer *);
    static doublereal bignum;
    extern doublereal zlange_(char *, integer *, integer *, doublecomplex *,
                              integer *, doublereal *);
    extern /* Subroutine */ int zgehrd_(integer *, integer *, integer *,
                                        doublecomplex *, integer *, doublecomplex *, doublecomplex *,
                                        integer *, integer *), zlascl_(char *, integer *, integer *,
                                                doublereal *, doublereal *, integer *, integer *, doublecomplex *,
                                                integer *, integer *), zlacpy_(char *, integer *,
                                                        integer *, doublecomplex *, integer *, doublecomplex *, integer *);
    static integer minwrk, maxwrk;
    static logical wantvl, wntsnb;
    static integer hswork;
    static logical wntsne;
    static doublereal smlnum;
    extern /* Subroutine */ int zhseqr_(char *, char *, integer *, integer *,
                                        integer *, doublecomplex *, integer *, doublecomplex *,
                                        doublecomplex *, integer *, doublecomplex *, integer *, integer *);
    static logical wantvr;
    extern /* Subroutine */ int ztrevc_(char *, char *, logical *, integer *,
                                        doublecomplex *, integer *, doublecomplex *, integer *,
                                        doublecomplex *, integer *, integer *, integer *, doublecomplex *,
                                        doublereal *, integer *), ztrsna_(char *, char *,
                                                logical *, integer *, doublecomplex *, integer *, doublecomplex *
                                                , integer *, doublecomplex *, integer *, doublereal *, doublereal
                                                *, integer *, integer *, doublecomplex *, integer *, doublereal *,
                                                integer *), zunghr_(integer *, integer *,
                                                        integer *, doublecomplex *, integer *, doublecomplex *,
                                                        doublecomplex *, integer *, integer *);
    static logical wntsnn, wntsnv;
    static char job[1];
    static doublereal scl, dum[1], eps;
    static doublecomplex tmp;



#define DUM(I) dum[(I)]
#define W(I) w[(I)-1]
#define SCALE(I) scale[(I)-1]
#define RCONDE(I) rconde[(I)-1]
#define RCONDV(I) rcondv[(I)-1]
#define WORK(I) work[(I)-1]
#define RWORK(I) rwork[(I)-1]

#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)]
#define VL(I,J) vl[(I)-1 + ((J)-1)* ( *ldvl)]
#define VR(I,J) vr[(I)-1 + ((J)-1)* ( *ldvr)]

    *info = 0;
    wantvl = lsame_(jobvl, "V");
    wantvr = lsame_(jobvr, "V");
    wntsnn = lsame_(sense, "N");
    wntsne = lsame_(sense, "E");
    wntsnv = lsame_(sense, "V");
    wntsnb = lsame_(sense, "B");
    if (! (lsame_(balanc, "N") || lsame_(balanc, "S") ||
            lsame_(balanc, "P") || lsame_(balanc, "B"))) {
        *info = -1;
    } else if (! wantvl && ! lsame_(jobvl, "N")) {
        *info = -2;
    } else if (! wantvr && ! lsame_(jobvr, "N")) {
        *info = -3;
    } else if (! (wntsnn || wntsne || wntsnb || wntsnv) || (wntsne || wntsnb)
               && ! (wantvl && wantvr)) {
        *info = -4;
    } else if (*n < 0) {
        *info = -5;
    } else if (*lda < max(1,*n)) {
        *info = -7;
    } else if (*ldvl < 1 || wantvl && *ldvl < *n) {
        *info = -10;
    } else if (*ldvr < 1 || wantvr && *ldvr < *n) {
        *info = -12;
    }

    /*     Compute workspace
            (Note: Comments in the code beginning "Workspace:" describe the
             minimal amount of workspace needed at that point in the code,
             as well as the preferred amount for good performance.
             CWorkspace refers to complex workspace, and RWorkspace to real
             workspace. NB refers to the optimal block size for the
             immediately following subroutine, as returned by ILAENV.
             HSWORK refers to the workspace preferred by ZHSEQR, as
             calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
             the worst case.) */

    minwrk = 1;
    if (*info == 0 && *lwork >= 1) {
        maxwrk = *n + *n * ilaenv_(&c__1, "ZGEHRD", " ", n, &c__1, n, &c__0,
                                   6L, 1L);
        if (! wantvl && ! wantvr) {
            /* Computing MAX */
            i__1 = 1, i__2 = *n << 1;
            minwrk = max(i__1,i__2);
            if (! (wntsnn || wntsne)) {
                /* Computing MAX */
                i__1 = minwrk, i__2 = *n * *n + (*n << 1);
                minwrk = max(i__1,i__2);
            }
            /* Computing MAX */
            i__1 = ilaenv_(&c__8, "ZHSEQR", "SN", n, &c__1, n, &c_n1, 6L, 2L);
            maxb = max(i__1,2);
            if (wntsnn) {
                /* Computing MIN
                   Computing MAX */
                i__3 = 2, i__4 = ilaenv_(&c__4, "ZHSEQR", "EN", n, &c__1, n, &
                                         c_n1, 6L, 2L);
                i__1 = min(maxb,*n), i__2 = max(i__3,i__4);
                k = min(i__1,i__2);
            } else {
                /* Computing MIN
                   Computing MAX */
                i__3 = 2, i__4 = ilaenv_(&c__4, "ZHSEQR", "SN", n, &c__1, n, &
                                         c_n1, 6L, 2L);
                i__1 = min(maxb,*n), i__2 = max(i__3,i__4);
                k = min(i__1,i__2);
            }
            /* Computing MAX */
            i__1 = k * (k + 2), i__2 = *n << 1;
            hswork = max(i__1,i__2);
            /* Computing MAX */
            i__1 = max(maxwrk,1);
            maxwrk = max(i__1,hswork);
            if (! (wntsnn || wntsne)) {
                /* Computing MAX */
                i__1 = maxwrk, i__2 = *n * *n + (*n << 1);
                maxwrk = max(i__1,i__2);
            }
        } else {
            /* Computing MAX */
            i__1 = 1, i__2 = *n << 1;
            minwrk = max(i__1,i__2);
            if (! (wntsnn || wntsne)) {
                /* Computing MAX */
                i__1 = minwrk, i__2 = *n * *n + (*n << 1);
                minwrk = max(i__1,i__2);
            }
            /* Computing MAX */
            i__1 = ilaenv_(&c__8, "ZHSEQR", "SN", n, &c__1, n, &c_n1, 6L, 2L);
            maxb = max(i__1,2);
            /* Computing MIN
               Computing MAX */
            i__3 = 2, i__4 = ilaenv_(&c__4, "ZHSEQR", "EN", n, &c__1, n, &
                                     c_n1, 6L, 2L);
            i__1 = min(maxb,*n), i__2 = max(i__3,i__4);
            k = min(i__1,i__2);
            /* Computing MAX */
            i__1 = k * (k + 2), i__2 = *n << 1;
            hswork = max(i__1,i__2);
            /* Computing MAX */
            i__1 = max(maxwrk,1);
            maxwrk = max(i__1,hswork);
            /* Computing MAX */
            i__1 = maxwrk, i__2 = *n + (*n - 1) * ilaenv_(&c__1, "ZUNGHR",
                                  " ", n, &c__1, n, &c_n1, 6L, 1L);
            maxwrk = max(i__1,i__2);
            if (! (wntsnn || wntsne)) {
                /* Computing MAX */
                i__1 = maxwrk, i__2 = *n * *n + (*n << 1);
                maxwrk = max(i__1,i__2);
            }
            /* Computing MAX */
            i__1 = maxwrk, i__2 = *n << 1, i__1 = max(i__1,i__2);
            maxwrk = max(i__1,1);
        }
        WORK(1).r = (doublereal) maxwrk, WORK(1).i = 0.;
    }
    if (*lwork < minwrk) {
        *info = -20;
    }
    if (*info != 0) {
        i__1 = -(*info);
        xerbla_("ZGEEVX", &i__1);
        return 0;
    }

    /*     Quick return if possible */

    if (*n == 0) {
        return 0;
    }

    /*     Get machine constants */

    eps = dlamch_("P");
    smlnum = dlamch_("S");
    bignum = 1. / smlnum;
    dlabad_(&smlnum, &bignum);
    smlnum = sqrt(smlnum) / eps;
    bignum = 1. / smlnum;

    /*     Scale A if max element outside range [SMLNUM,BIGNUM] */

    icond = 0;
    anrm = zlange_("M", n, n, &A(1,1), lda, dum);
    scalea = FALSE_;
    if (anrm > 0. && anrm < smlnum) {
        scalea = TRUE_;
        cscale = smlnum;
    } else if (anrm > bignum) {
        scalea = TRUE_;
        cscale = bignum;
    }
    if (scalea) {
        zlascl_("G", &c__0, &c__0, &anrm, &cscale, n, n, &A(1,1), lda, &
                ierr);
    }

    /*     Balance the matrix and compute ABNRM */

    zgebal_(balanc, n, &A(1,1), lda, ilo, ihi, &SCALE(1), &ierr);
    *abnrm = zlange_("1", n, n, &A(1,1), lda, dum);
    if (scalea) {
        DUM(0) = *abnrm;
        dlascl_("G", &c__0, &c__0, &cscale, &anrm, &c__1, &c__1, dum, &c__1, &
                ierr);
        *abnrm = DUM(0);
    }

    /*     Reduce to upper Hessenberg form
           (CWorkspace: need 2*N, prefer N+N*NB)
           (RWorkspace: none) */

    itau = 1;
    iwrk = itau + *n;
    i__1 = *lwork - iwrk + 1;
    zgehrd_(n, ilo, ihi, &A(1,1), lda, &WORK(itau), &WORK(iwrk), &i__1, &
            ierr);

    if (wantvl) {

        /*        Want left eigenvectors
                  Copy Householder vectors to VL */

        *(unsigned char *)side = 'L';
        zlacpy_("L", n, n, &A(1,1), lda, &VL(1,1), ldvl);

        /*        Generate unitary matrix in VL
                  (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
                  (RWorkspace: none) */

        i__1 = *lwork - iwrk + 1;
        zunghr_(n, ilo, ihi, &VL(1,1), ldvl, &WORK(itau), &WORK(iwrk), &
                i__1, &ierr);

        /*        Perform QR iteration, accumulating Schur vectors in VL
                  (CWorkspace: need 1, prefer HSWORK (see comments) )
                  (RWorkspace: none) */

        iwrk = itau;
        i__1 = *lwork - iwrk + 1;
        zhseqr_("S", "V", n, ilo, ihi, &A(1,1), lda, &W(1), &VL(1,1), ldvl, &WORK(iwrk), &i__1, info);

        if (wantvr) {

            /*           Want left and right eigenvectors
                         Copy Schur vectors to VR */

            *(unsigned char *)side = 'B';
            zlacpy_("F", n, n, &VL(1,1), ldvl, &VR(1,1), ldvr)
            ;
        }

    } else if (wantvr) {

        /*        Want right eigenvectors
                  Copy Householder vectors to VR */

        *(unsigned char *)side = 'R';
        zlacpy_("L", n, n, &A(1,1), lda, &VR(1,1), ldvr);

        /*        Generate unitary matrix in VR
                  (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
                  (RWorkspace: none) */

        i__1 = *lwork - iwrk + 1;
        zunghr_(n, ilo, ihi, &VR(1,1), ldvr, &WORK(itau), &WORK(iwrk), &
                i__1, &ierr);

        /*        Perform QR iteration, accumulating Schur vectors in VR
                  (CWorkspace: need 1, prefer HSWORK (see comments) )
                  (RWorkspace: none) */

        iwrk = itau;
        i__1 = *lwork - iwrk + 1;
        zhseqr_("S", "V", n, ilo, ihi, &A(1,1), lda, &W(1), &VR(1,1), ldvr, &WORK(iwrk), &i__1, info);

    } else {

        /*        Compute eigenvalues only
                  If condition numbers desired, compute Schur form */

        if (wntsnn) {
            *(unsigned char *)job = 'E';
        } else {
            *(unsigned char *)job = 'S';
        }

        /*        (CWorkspace: need 1, prefer HSWORK (see comments) )
                  (RWorkspace: none) */

        iwrk = itau;
        i__1 = *lwork - iwrk + 1;
        zhseqr_(job, "N", n, ilo, ihi, &A(1,1), lda, &W(1), &VR(1,1), ldvr, &WORK(iwrk), &i__1, info);
    }

    /*     If INFO > 0 from ZHSEQR, then quit */

    if (*info > 0) {
        goto L50;
    }

    if (wantvl || wantvr) {

        /*        Compute left and/or right eigenvectors
                  (CWorkspace: need 2*N)
                  (RWorkspace: need N) */

        ztrevc_(side, "B", select, n, &A(1,1), lda, &VL(1,1), ldvl,
                &VR(1,1), ldvr, n, &nout, &WORK(iwrk), &RWORK(1), &
                ierr);
    }

    /*     Compute condition numbers if desired
           (CWorkspace: need N*N+2*N unless SENSE = 'E')
           (RWorkspace: need 2*N unless SENSE = 'E') */

    if (! wntsnn) {
        ztrsna_(sense, "A", select, n, &A(1,1), lda, &VL(1,1),
                ldvl, &VR(1,1), ldvr, &RCONDE(1), &RCONDV(1), n, &nout,
                &WORK(iwrk), n, &RWORK(1), &icond);
    }

    if (wantvl) {

        /*        Undo balancing of left eigenvectors */

        zgebak_(balanc, "L", n, ilo, ihi, &SCALE(1), n, &VL(1,1), ldvl,
                &ierr);

        /*        Normalize left eigenvectors and make largest component real
        */

        i__1 = *n;
        for (i = 1; i <= *n; ++i) {
            scl = 1. / dznrm2_(n, &VL(1,i), &c__1);
            zdscal_(n, &scl, &VL(1,i), &c__1);
            i__2 = *n;
            for (k = 1; k <= *n; ++k) {
                i__3 = k + i * vl_dim1;
                /* Computing 2nd power */
                d__1 = VL(k,i).r;
                /* Computing 2nd power */
                d__2 = d_imag(&VL(k,i));
                RWORK(k) = d__1 * d__1 + d__2 * d__2;
                /* L10: */
            }
            k = idamax_(n, &RWORK(1), &c__1);
            d_cnjg(&z__2, &VL(k,i));
            d__1 = sqrt(RWORK(k));
            z__1.r = z__2.r / d__1, z__1.i = z__2.i / d__1;
            tmp.r = z__1.r, tmp.i = z__1.i;
            zscal_(n, &tmp, &VL(1,i), &c__1);
            i__2 = k + i * vl_dim1;
            i__3 = k + i * vl_dim1;
            d__1 = VL(k,i).r;
            z__1.r = d__1, z__1.i = 0.;
            VL(k,i).r = z__1.r, VL(k,i).i = z__1.i;
            /* L20: */
        }
    }

    if (wantvr) {

        /*        Undo balancing of right eigenvectors */

        zgebak_(balanc, "R", n, ilo, ihi, &SCALE(1), n, &VR(1,1), ldvr,
                &ierr);

        /*        Normalize right eigenvectors and make largest component real
         */

        i__1 = *n;
        for (i = 1; i <= *n; ++i) {
            scl = 1. / dznrm2_(n, &VR(1,i), &c__1);
            zdscal_(n, &scl, &VR(1,i), &c__1);
            i__2 = *n;
            for (k = 1; k <= *n; ++k) {
                i__3 = k + i * vr_dim1;
                /* Computing 2nd power */
                d__1 = VR(k,i).r;
                /* Computing 2nd power */
                d__2 = d_imag(&VR(k,i));
                RWORK(k) = d__1 * d__1 + d__2 * d__2;
                /* L30: */
            }
            k = idamax_(n, &RWORK(1), &c__1);
            d_cnjg(&z__2, &VR(k,i));
            d__1 = sqrt(RWORK(k));
            z__1.r = z__2.r / d__1, z__1.i = z__2.i / d__1;
            tmp.r = z__1.r, tmp.i = z__1.i;
            zscal_(n, &tmp, &VR(1,i), &c__1);
            i__2 = k + i * vr_dim1;
            i__3 = k + i * vr_dim1;
            d__1 = VR(k,i).r;
            z__1.r = d__1, z__1.i = 0.;
            VR(k,i).r = z__1.r, VR(k,i).i = z__1.i;
            /* L40: */
        }
    }

    /*     Undo scaling if necessary */

L50:
    if (scalea) {
        i__1 = *n - *info;
        /* Computing MAX */
        i__3 = *n - *info;
        i__2 = max(i__3,1);
        zlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &W(*info + 1)
                , &i__2, &ierr);
        if (*info == 0) {
            if ((wntsnv || wntsnb) && icond == 0) {
                dlascl_("G", &c__0, &c__0, &cscale, &anrm, n, &c__1, &RCONDV(
                            1), n, &ierr);
            }
        } else {
            i__1 = *ilo - 1;
            zlascl_("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &W(1), n,
                    &ierr);
        }
    }

    WORK(1).r = (doublereal) maxwrk, WORK(1).i = 0.;
    return 0;

    /*     End of ZGEEVX */

} /* zgeevx_ */
ScreenMiniMenu::ScreenMiniMenu( Menu* pDef, ScreenMessage SM_SendOnOK, ScreenMessage SM_SendOnCancel ) :
  Screen("ScreenMiniMenu")
{
	m_bIsTransparent = true;	// draw screens below us

	m_SMSendOnOK = SM_SendOnOK;
	m_SMSendOnCancel = SM_SendOnCancel;
	m_Def = *pDef;
	ASSERT( m_Def.rows.size() <= MAX_MENU_ROWS );


	m_Background.LoadFromAniDir( THEME->GetPathToB("ScreenMiniMenu background") );
	this->AddChild( &m_Background );

	float fHeightOfAll = min( SCREEN_HEIGHT-80, (m_Def.rows.size()-1)*SPACING_Y );

	m_textTitle.LoadFromFont( THEME->GetPathToF("Common normal") );
	m_textTitle.SetText( m_Def.title );
	m_textTitle.SetXY( CENTER_X, CENTER_Y - fHeightOfAll/2 - 30 );
	m_textTitle.SetZoom( 0.8f );
	this->AddChild( &m_textTitle );

	bool bMarkedFirstEnabledLine = false;
	m_iCurLine = 0;

	float fLongestLabelPlusAnswer = 0;

	for( unsigned i=0; i<m_Def.rows.size(); i++ )
	{
		MenuRowInternal& line = m_Def.rows[i];
		m_iCurAnswers[i] = 0;

		float fY;
		if( m_Def.rows.size() > 1 )
			fY = SCALE( i, 0.f, m_Def.rows.size()-1.f, CENTER_Y-fHeightOfAll/2, CENTER_Y+fHeightOfAll/2 );
		else
			fY = CENTER_Y;

		m_textLabel[i].LoadFromFont( THEME->GetPathToF("Common normal") );
		m_textLabel[i].SetText( line.name );
		m_textLabel[i].SetY( fY );
		m_textLabel[i].SetZoom( ZOOM_NOT_SELECTED );
		m_textLabel[i].SetHorizAlign( Actor::align_left );
		m_textLabel[i].SetDiffuse( line.enabled ? COLOR_ENABLED : COLOR_DISABLED );
		this->AddChild( &m_textLabel[i] );

		m_textAnswer[i].LoadFromFont( THEME->GetPathToF("Common normal") );
		m_textAnswer[i].SetY( fY );
		m_textAnswer[i].SetZoom( ZOOM_NOT_SELECTED );
		m_textAnswer[i].SetHorizAlign( Actor::align_right );
		m_textAnswer[i].SetDiffuse( line.enabled ? COLOR_ENABLED : COLOR_DISABLED );
		this->AddChild( &m_textAnswer[i] );

		for( unsigned j = 0; j < line.choices.size(); ++j )
		{
	 		m_textAnswer[i].SetText( line.choices[j] );
			fLongestLabelPlusAnswer = max( 
				fLongestLabelPlusAnswer, 
				m_textLabel[i].GetUnzoomedWidth() * ZOOM_SELECTED +
				m_textAnswer[i].GetUnzoomedWidth() * ZOOM_SELECTED );
		}

		ASSERT_M( line.choices.empty() || line.defaultChoice < (int) line.choices.size(),
			ssprintf("%i, %i", line.defaultChoice, (int) line.choices.size()) );
		CString sText = line.choices.empty() ? CString("") : line.choices[line.defaultChoice];
 		m_textAnswer[i].SetText( sText );

		if( !bMarkedFirstEnabledLine && line.enabled )
		{
			m_iCurLine = i;
			AfterLineChanged();
			bMarkedFirstEnabledLine = true;
		}

		m_iCurAnswers[i] = line.defaultChoice;
	}

	// adjust text spacing based on widest line
	float fLabelX = LABEL_X;
	float fAnswerX = ANSWER_X;
	float fDefaultWidth = ANSWER_X - LABEL_X;
	if( fLongestLabelPlusAnswer+20 > fDefaultWidth )
	{
		float fIncreaseBy = fLongestLabelPlusAnswer - fDefaultWidth + 20;
		fLabelX -= fIncreaseBy/2;
		fAnswerX += fIncreaseBy/2;
	}

	for( unsigned k=0; k<m_Def.rows.size(); k++ )
	{
		m_textLabel[k].SetX( fLabelX );
		m_textAnswer[k].SetX( fAnswerX );
	}

	m_In.Load( THEME->GetPathToB("ScreenMiniMenu in") );
	m_In.StartTransitioning();
	this->AddChild( &m_In );

	m_Out.Load( THEME->GetPathToB("ScreenMiniMenu out") );
	this->AddChild( &m_Out );
}
OP_ERROR
SOP_Ocean::cookMySop(OP_Context &context)
{
    float now = context.getTime();

    //std::cout << "cook ocean, t = " << now << std::endl;

    // lock inputs
    if (lockInputs(context) >= UT_ERROR_ABORT )
    {
        return error();
    }


    GEO_Point		*ppt;
    UT_Interrupt	*boss;

    // Check to see that there hasn't been a critical error in cooking the SOP.
    if (error() < UT_ERROR_ABORT)
    {
        boss = UTgetInterrupt();

        // Start the interrupt server
        boss->opStart("Updating Ocean");

        duplicatePointSource(0,context);

        int   gridres  = 1 << int(GRID_RES(now));
        float stepsize = GRID_SIZE(now) / (float)gridres;

        bool do_chop     = CHOP(now);
        bool do_jacobian = JACOBIAN(now);
        bool do_normals  = NORMALS(now) && !do_chop;

        if (!_ocean || _ocean_needs_rebuild)
        {
            if (_ocean)
            {
                delete _ocean;
            }

            if (_ocean_context)
            {
                delete _ocean_context;
            }

            _ocean = new drw::Ocean(gridres,gridres,stepsize,stepsize,
                                    V(0),L(0),1.0,W(0),1-DAMP(0),ALIGN(0),
                                    DEPTH(0),SEED(0));
            _ocean_scale   = _ocean->get_height_normalize_factor();

            _ocean_context = _ocean->new_context(true,do_chop,do_normals,do_jacobian);

            _ocean_needs_rebuild = false;
//             std::cout << "######### SOP, rebuilt ocean, norm_factor = " << _ocean_scale 
//                       << " chop = " << do_chop 
//                       << " norm = " << do_normals
//                       << " jacobian = " << do_jacobian
//                       << std::endl;
        }

        float chop_amount = CHOPAMOUNT(now);

        // sum up the waves at this timestep
        _ocean->update(TIME(now),*_ocean_context,true,do_chop,do_normals,do_jacobian,
                       _ocean_scale * SCALE(now),chop_amount);

        bool linterp = ! INTERP(now);


        // get our attribute indices
        GA_RWAttributeRef normal_index;
        GA_RWAttributeRef jminus_index;
        GA_RWAttributeRef eminus_index;

        if (do_normals)
        {
            normal_index = gdp->addNormalAttribute(GEO_POINT_DICT);
        }
        if (do_jacobian)
        {
            // jminus_index = gdp->addPointAttrib("mineigval",sizeof(float),GB_ATTRIB_FLOAT,0);
            // eminus_index = gdp->addPointAttrib("mineigvec",sizeof(UT_Vector3),GB_ATTRIB_VECTOR,0);
            jminus_index = gdp->addTuple(GA_STORE_REAL32,GA_ATTRIB_POINT,"mineigval",1,GA_Defaults(0));
            eminus_index = gdp->addFloatTuple(GA_ATTRIB_POINT,"mineigvec",1,GA_Defaults(0));
        }

        // this is not that fast, can it be done quicker ???
        GA_FOR_ALL_GPOINTS(gdp, ppt)
            {
                UT_Vector4 p = ppt->getPos();

                
                if (linterp)
                {
                    _ocean_context->eval_xz(p(0),p(2));
                }
                else
                {
                    _ocean_context->eval2_xz(p(0),p(2));
                }

                if (do_chop) 
                {
                    p.assign( p(0) + _ocean_context->disp[0],
                              p(1) + _ocean_context->disp[1],
                              p(2) + _ocean_context->disp[2] );
                }
                else
                {
                    // ppt->getPos()(1) += _ocean_context->disp[1];
                	UT_Vector4 tmp_p = ppt->getPos();
                	tmp_p(1) += _ocean_context->disp[1];
                	ppt->setPos(tmp_p);
                }

                if (do_normals)
                {
                	/*
					  UT_Vector3* normal = (UT_Vector3*) ppt->castAttribData<UT_Vector3>(normal_index);
					  normal->assign(_ocean_context->normal[0],
					                 _ocean_context->normal[1],
					                 _ocean_context->normal[2]);
					  normal->normalize();
                    */
                	ppt->getValue<UT_Vector3>(normal_index).assign(_ocean_context->normal[0],
																   _ocean_context->normal[1],
																   _ocean_context->normal[2]);
                	ppt->getValue<UT_Vector3>(normal_index).normalize();
                }

                if (do_jacobian)
                {/*
                    float *js = (float*)ppt->castAttribData<float>(jminus_index);
                    *js = _ocean_context->Jminus;
                    UT_Vector3* eminus = (UT_Vector3*)ppt->castAttribData<UT_Vector3>(eminus_index);
                    eminus->assign(_ocean_context->Eminus[0],0,_ocean_context->Eminus[1]);
                    */
                    ppt->setValue<float>(jminus_index,_ocean_context->Jminus);
                    ppt->getValue<UT_Vector3>(eminus_index).assign(_ocean_context->Eminus[0],0,_ocean_context->Eminus[1]);
                }
				ppt->setPos(p);
            }
static inline s8 TEMP_TO_REG(int val)
{
	return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000);
}
Exemple #9
0
void
ht_dump_statistics (hash_table *table)
{
  size_t nelts, nids, overhead, headers;
  size_t total_bytes, longest;
  double sum_of_squares, exp_len, exp_len2, exp2_len;
  hashnode *p, *limit;

#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
                  ? (x) \
                  : ((x) < 1024*1024*10 \
                     ? (x) / 1024 \
                     : (x) / (1024*1024))))
#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))

  total_bytes = longest = sum_of_squares = nids = 0;
  p = table->entries;
  limit = p + table->nslots;
  do
    if (*p)
      {
        size_t n = HT_LEN (*p);

        total_bytes += n;
        sum_of_squares += (double) n * n;
        if (n > longest)
          longest = n;
        nids++;
      }
  while (++p < limit);

  nelts = table->nelements;
  overhead = obstack_memory_used (&table->stack) - total_bytes;
  headers = table->nslots * sizeof (hashnode);

  fprintf (stderr, "\nString pool\nentries\t\t%lu\n",
           (unsigned long) nelts);
  fprintf (stderr, "identifiers\t%lu (%.2f%%)\n",
           (unsigned long) nids, nids * 100.0 / nelts);
  fprintf (stderr, "slots\t\t%lu\n",
           (unsigned long) table->nslots);
  fprintf (stderr, "bytes\t\t%lu%c (%lu%c overhead)\n",
           SCALE (total_bytes), LABEL (total_bytes),
           SCALE (overhead), LABEL (overhead));
  fprintf (stderr, "table size\t%lu%c\n",
           SCALE (headers), LABEL (headers));

  exp_len = (double)total_bytes / (double)nelts;
  exp2_len = exp_len * exp_len;
  exp_len2 = (double) sum_of_squares / (double) nelts;

  fprintf (stderr, "coll/search\t%.4f\n",
           (double) table->collisions / (double) table->searches);
  fprintf (stderr, "ins/search\t%.4f\n",
           (double) nelts / (double) table->searches);
  fprintf (stderr, "avg. entry\t%.2f bytes (+/- %.2f)\n",
           exp_len, approx_sqrt (exp_len2 - exp2_len));
  fprintf (stderr, "longest entry\t%lu\n",
           (unsigned long) longest);
#undef SCALE
#undef LABEL
}
Exemple #10
0
// Draw background rectangles for a dropdown
void dropdown_drawactive(void) {
    DROPDOWN *drop = active_dropdown;
    if (!drop) {
        return;
    }

    // load colors for this style
    uint32_t color_bg,
             color_border,
             color_aoptbg,
             color_aopttext,
             color_text;

    switch (drop->style) {
        case AUXILIARY_STYLE:
            color_bg = COLOR_BACKGROUND_AUX;
            color_border = COLOR_AUX_EDGE_ACTIVE;
            color_aoptbg = COLOR_AUX_ACTIVEOPTION_BACKGROUND;
            color_aopttext = COLOR_AUX_ACTIVEOPTION_TEXT;
            color_text = COLOR_AUX_TEXT;
            break;
        default:
            color_bg = COLOR_BACKGROUND_MAIN;
            color_border = COLOR_EDGE_ACTIVE;
            color_aoptbg = COLOR_ACTIVEOPTION_BACKGROUND;
            color_aopttext = COLOR_ACTIVEOPTION_TEXT;
            color_text = COLOR_MAIN_TEXT;
            break;
    }

    int x = active_x, y = active_y, w = active_width, h = active_height;

    int i, sign = 1;

    // Increase width if needed, so that all menu items fit.
    for (i = 0; i != drop->dropcount; i++) {
        STRING* e = drop->ondisplay(i, drop);
        int needed_w = textwidth(e->str, e->length) + SCALE(8);
        if(w < needed_w) {
            w = needed_w;
        }
    }

    if (y + h * drop->dropcount > settings.window_height) {
        // y -= h * (drop->dropcount - 1);
        // sign = -1;
    }
    y -= h * drop->selected;

    draw_rect_fill (x, y, w, h * drop->dropcount, color_bg);
    draw_rect_frame(x, y, w, h * drop->dropcount, color_border);

    if(sign == -1) {
        y += h * (drop->dropcount - 1);
    }

    for (i = 0; i != drop->dropcount; i++) {
        // int j = index(drop, i);
        int j = i;
        STRING* e = drop->ondisplay(j, drop);
        if(j == drop->over) {
            draw_rect_fill(x + 1, y + 1, w - 2, h - 2, color_aoptbg);
            setcolor(color_aopttext);
        } else {
            setcolor(color_text);
        }
        setfont(FONT_TEXT);
        drawtext(x + SCALE(4), y + SCALE(4), e->str, e->length);

        y += sign * h;
    }
}
Exemple #11
0
bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int page, int pagecount)
{
	uint32 height=head.biHeight;
	uint32 width=head.biWidth;
	uint16 bitcount=head.biBitCount;
	uint16 bitspersample;
	uint16 samplesperpixel;
	uint16 photometric=0;
	uint16 compression;
//	uint16 pitch;
//	int line;
	uint32 x, y;

	samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (BYTE)3 : (BYTE)1;
#if CXIMAGE_SUPPORT_ALPHA
	if (bitcount==24 && AlphaIsValid()) { bitcount=32; samplesperpixel=4; }
#endif //CXIMAGE_SUPPORT_ALPHA

	bitspersample = bitcount / samplesperpixel;

	//set the PHOTOMETRIC tag
	RGBQUAD *rgb = GetPalette();
	switch (bitcount) {
		case 1:
			if (CompareColors(&rgb[0],&rgb[1])<0) {
				/* <abe> some viewers do not handle PHOTOMETRIC_MINISBLACK:
				 * let's transform the image in PHOTOMETRIC_MINISWHITE
				 */
				//invert the colors
				RGBQUAD tempRGB=GetPaletteColor(0);
				SetPaletteColor(0,GetPaletteColor(1));
				SetPaletteColor(1,tempRGB);
				//invert the pixels
				BYTE *iSrc=info.pImage;
				for (unsigned long i=0;i<head.biSizeImage;i++){
					*iSrc=(BYTE)~(*(iSrc));
					iSrc++;
				}
				photometric = PHOTOMETRIC_MINISWHITE;
				//photometric = PHOTOMETRIC_MINISBLACK;
			} else {
				photometric = PHOTOMETRIC_MINISWHITE;
			}
			break;
		case 4:	// Check if the DIB has a color or a greyscale palette
		case 8:
			photometric = PHOTOMETRIC_MINISBLACK; //default to gray scale
			for (x = 0; x < head.biClrUsed; x++) {
				if ((rgb->rgbRed != x)||(rgb->rgbRed != rgb->rgbGreen)||(rgb->rgbRed != rgb->rgbBlue)){
					photometric = PHOTOMETRIC_PALETTE;
					break;
				}
				rgb++;
			}
			break;
		case 24:
		case 32:
			photometric = PHOTOMETRIC_RGB;			
			break;
	}

#if CXIMAGE_SUPPORT_ALPHA
	if (AlphaIsValid() && bitcount==8) samplesperpixel=2; //8bpp + alpha layer
#endif //CXIMAGE_SUPPORT_ALPHA

//	line = CalculateLine(width, bitspersample * samplesperpixel);
//	pitch = (uint16)CalculatePitch(line);

	//prepare the palette struct
	RGBQUAD pal[256];
	if (GetPalette()){
		BYTE b;
		memcpy(pal,GetPalette(),GetPaletteSize());
		for(WORD a=0;a<head.biClrUsed;a++){	//swap blue and red components
			b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b;
		}
	}

	// handle standard width/height/bpp stuff
	TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width);
	TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height);
	TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
	TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
	TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric);
	TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);	// single image plane 
	TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

	uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1);  //<REC> gives better compression
	TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);

	// handle metrics
	TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
	TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)info.xDPI);
	TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)info.yDPI);
//	TIFFSetField(m_tif, TIFFTAG_XPOSITION, (float)info.xOffset);
//	TIFFSetField(m_tif, TIFFTAG_YPOSITION, (float)info.yOffset);

	// multi-paging - Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
	if (multipage)
	{
		char page_number[20];
		sprintf(page_number, "Page %d", page);

		TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
		TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page,pagecount);
		TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number);
	} else {
		TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0);
	}

	// palettes (image colormaps are automatically scaled to 16-bits)
	if (photometric == PHOTOMETRIC_PALETTE) {
		uint16 *r, *g, *b;
		r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256);
		g = r + 256;
		b = g + 256;

		for (int i = 255; i >= 0; i--) {
			b[i] = (uint16)SCALE((uint16)pal[i].rgbRed);
			g[i] = (uint16)SCALE((uint16)pal[i].rgbGreen);
			r[i] = (uint16)SCALE((uint16)pal[i].rgbBlue);
		}

		TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b);
		_TIFFfree(r);
	}

	// compression
	if (info.dwCodecOption) {
		compression = (WORD)info.dwCodecOption;
	} else {
		switch (bitcount) {
			case 1 :
				compression = COMPRESSION_CCITTFAX4;
				break;
			case 8 :
				compression = COMPRESSION_PACKBITS;
				break;
			case 24 :
			case 32 :
				compression = COMPRESSION_JPEG;
				break;
			default :
				compression = COMPRESSION_NONE;
				break;
		}
	}
	TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);

	switch (compression) {
	case COMPRESSION_JPEG:
		TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, info.nQuality);
		TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, ((7+rowsperstrip)>>3)<<3);
   		break;
	case COMPRESSION_LZW:
		if (bitcount>=8) TIFFSetField(m_tif, TIFFTAG_PREDICTOR, 2);
		break;
	}

	// read the DIB lines from bottom to top and save them in the TIF

	BYTE *bits;
	switch(bitcount) {				
		case 1 :
		case 4 :
		case 8 :
		{
			if (samplesperpixel==1){
				for (y = 0; y < height; y++) {
					bits= info.pImage + (height - y - 1)*info.dwEffWidth;
					if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) return false;
				}
			}
#if CXIMAGE_SUPPORT_ALPHA
			else { //8bpp + alpha layer
				bits = (BYTE*)malloc(2*width);
				if (!bits) return false;
				for (y = 0; y < height; y++) {
					for (x=0;x<width;x++){
						bits[2*x]=GetPixelIndex(x,height - y - 1);
						bits[2*x+1]=AlphaGet(x,height - y - 1);
					}
					if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) {
						free(bits);
						return false;
					}
				}
				free(bits);
			}
#endif //CXIMAGE_SUPPORT_ALPHA
			break;
		}				
		case 24:
		{
			BYTE *buffer = (BYTE *)malloc(info.dwEffWidth);
			if (!buffer) return false;
			for (y = 0; y < height; y++) {
				// get a pointer to the scanline
				memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
				// TIFFs store color data RGB instead of BGR
				BYTE *pBuf = buffer;
				for (x = 0; x < width; x++) {
					BYTE tmp = pBuf[0];
					pBuf[0] = pBuf[2];
					pBuf[2] = tmp;
					pBuf += 3;
				}
				// write the scanline to disc
				if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
					free(buffer);
					return false;
				}
			}
			free(buffer);
			break;
		}				
		case 32 :
		{
#if CXIMAGE_SUPPORT_ALPHA
			BYTE *buffer = (BYTE *)malloc((info.dwEffWidth*4)/3);
			if (!buffer) return false;
			for (y = 0; y < height; y++) {
				// get a pointer to the scanline
				memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
				// TIFFs store color data RGB instead of BGR
				BYTE *pSrc = buffer + 3 * width;
				BYTE *pDst = buffer + 4 * width;
				for (x = 0; x < width; x++) {
					pDst-=4;
					pSrc-=3;
					pDst[3] = AlphaGet(width-x-1,height-y-1);
					pDst[2] = pSrc[0];
					pDst[1] = pSrc[1];
					pDst[0] = pSrc[2];
				}
				// write the scanline to disc
				if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
					free(buffer);
					return false;
				}
			}
			free(buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
			break;
		}				
	}
	return true;
}
Exemple #12
0
void NoteDisplay::DrawHoldBottomCap( const TapNote& tn, int iCol, int iRow, bool bIsBeingHeld, float fYHead, float fYTail, int	fYStep, float fPercentFadeToFail, float fColorScale, bool bGlow, float fYStartOffset, float fYEndOffset )
{
	//
	// Draw the bottom cap (always wavy)
	//
	StripBuffer queue;

	Sprite* pBottomCap = GetHoldBottomCapSprite( NoteRowToBeat(iRow), tn.subType == TapNote::hold_head_roll, bIsBeingHeld );

	pBottomCap->SetZoom( ArrowEffects::GetZoom( m_pPlayerState ) );

	// draw manually in small segments
	RageTexture* pTexture = pBottomCap->GetTexture();
	const RectF *pRect = pBottomCap->GetCurrentTextureCoordRect();
	DISPLAY->ClearAllTextures();
	DISPLAY->SetTexture( 0, pTexture );
	DISPLAY->SetBlendMode( BLEND_NORMAL );
	DISPLAY->SetCullMode( CULL_NONE );
	DISPLAY->SetTextureWrapping(false);

	const float fFrameWidth		= pBottomCap->GetZoomedWidth();
	const float fFrameHeight	= pBottomCap->GetZoomedHeight();
	const float fYCapTop		= fYTail+cache->m_iStopDrawingHoldBodyOffsetFromTail;
	const float fYCapBottom		= fYTail+cache->m_iStopDrawingHoldBodyOffsetFromTail+fFrameHeight;

	bool bReverse = m_pPlayerState->m_CurrentPlayerOptions.GetReversePercentForColumn(iCol) > 0.5f;

	if( bGlow )
		fColorScale = 1;

	float fDrawYCapTop;
	float fDrawYCapBottom;
	{
		float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYStartOffset, m_fYReverseOffsetPixels );
		float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYEndOffset, m_fYReverseOffsetPixels );
		fDrawYCapTop = max( fYCapTop, bReverse ? fYEndPos : fYStartPos );
		fDrawYCapBottom = min( fYCapBottom, bReverse ? fYStartPos : fYEndPos );
	}

	bool bAllAreTransparent = true;
	bool bLast = false;
	// don't draw any part of the tail that is before the middle of the head
	float fY=max( fDrawYCapTop, fYHead );
	for( ; !bLast; fY += fYStep )
	{
		if( fY >= fDrawYCapBottom )
		{
			fY = fDrawYCapBottom;
			bLast = true;
		}

		const float fYOffset		= ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, iCol, fY, m_fYReverseOffsetPixels );
		const float fX			= ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset );
		const float fZ			= ArrowEffects::GetZPos( m_pPlayerState, iCol, fYOffset );

		// XXX: Actor rotations use degrees, RageFastCos/Sin use radians. Convert here.
		const float fRotationY		= ArrowEffects::GetRotationY( m_pPlayerState, fYOffset ) * PI/180;

		// if we're rotating, we need to modify the X and Z coords for the outer edges.
		const float fRotOffsetX		= fFrameWidth/2 * RageFastCos(fRotationY);
		const float fRotOffsetZ		= fFrameWidth/2 * RageFastSin(fRotationY);
		const float fXLeft		= fX - fRotOffsetX;
		const float fXRight		= fX + fRotOffsetX;
		const float fZLeft		= fZ - fRotOffsetZ;
		const float fZRight		= fZ + fRotOffsetZ;

		const float fTopDistFromTail	= fY - fYCapTop;
		const float fTexCoordTop	= SCALE( fTopDistFromTail,    0, fFrameHeight, pRect->top, pRect->bottom );
		const float fTexCoordLeft	= pRect->left;
		const float fTexCoordRight	= pRect->right;
		const float	fAlpha		= ArrowGetAlphaOrGlow( bGlow, m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
		const RageColor color		= RageColor(fColorScale,fColorScale,fColorScale,fAlpha);

		if( fAlpha > 0 )
			bAllAreTransparent = false;

		queue.v[0].p = RageVector3(fXLeft,  fY, fZLeft);	queue.v[0].c = color; queue.v[0].t = RageVector2(fTexCoordLeft,  fTexCoordTop);
		queue.v[1].p = RageVector3(fXRight, fY, fZRight);	queue.v[1].c = color; queue.v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);

		queue.v+=2;
		if( queue.Free() < 2 )
		{
			/* The queue is full.  Render it, clear the buffer, and move back a step to
			 * start off the quad strip again. */
			if( !bAllAreTransparent )
				queue.Draw();
			queue.Init();
			bAllAreTransparent = true;
			fY -= fYStep;
		}
	}
	if( !bAllAreTransparent )
		queue.Draw();
}
Exemple #13
0
void NoteDisplay::DrawHoldBody( const TapNote& tn, int iCol, int iRow, bool bIsBeingHeld, float fYHead, float fYTail, int fYStep, float fPercentFadeToFail, float fColorScale, bool bGlow,
							   float fYStartOffset, float fYEndOffset )
{
	//
	// Draw the body (always wavy)
	//
	StripBuffer queue;

	Sprite* pSprBody = GetHoldBodySprite( NoteRowToBeat(iRow), tn.subType == TapNote::hold_head_roll, bIsBeingHeld );

	pSprBody->SetZoom( ArrowEffects::GetZoom( m_pPlayerState ) );

	// draw manually in small segments
	RageTexture* pTexture = pSprBody->GetTexture();
	const RectF *pRect = pSprBody->GetCurrentTextureCoordRect();
	DISPLAY->ClearAllTextures();
	DISPLAY->SetTexture( 0, pTexture );
	DISPLAY->SetBlendMode( BLEND_NORMAL );
	DISPLAY->SetCullMode( CULL_NONE );
	DISPLAY->SetTextureWrapping( true );


	const float fFrameWidth  = pSprBody->GetZoomedWidth();
	const float fFrameHeight = pSprBody->GetZoomedHeight();
	const float fYBodyTop = fYHead + cache->m_iStartDrawingHoldBodyOffsetFromHead;
	const float fYBodyBottom = fYTail + cache->m_iStopDrawingHoldBodyOffsetFromTail;

	const bool bReverse = m_pPlayerState->m_CurrentPlayerOptions.GetReversePercentForColumn(iCol) > 0.5f;
	bool bAnchorToBottom = bReverse && cache->m_bFlipHeadAndTailWhenReverse;

	if( bGlow )
		fColorScale = 1;

	/* Only draw the section that's within the range specified.  If a hold note is
	 * very long, don't process or draw the part outside of the range.  Don't change
	 * fYBodyTop or fYBodyBottom; they need to be left alone to calculate texture
	 * coordinates. */
	float fDrawYBodyTop;
	float fDrawYBodyBottom;
	{
		float fYStartPos = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYStartOffset, m_fYReverseOffsetPixels );
		float fYEndPos = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYEndOffset, m_fYReverseOffsetPixels );

		fDrawYBodyTop = max( fYBodyTop, bReverse ? fYEndPos : fYStartPos );
		fDrawYBodyBottom = min( fYBodyBottom, bReverse ? fYStartPos : fYEndPos );
	}

	// top to bottom
	bool bAllAreTransparent = true;
	bool bLast = false;
	float fVertTexCoordOffset = 0;
	for( float fY = fDrawYBodyTop; !bLast; fY += fYStep )
	{
		if( fY >= fDrawYBodyBottom )
		{
			fY = fDrawYBodyBottom;
			bLast = true;
		}

		const float fYOffset		= ArrowEffects::GetYOffsetFromYPos( m_pPlayerState, iCol, fY, m_fYReverseOffsetPixels );
		const float fX			= ArrowEffects::GetXPos( m_pPlayerState, iCol, fYOffset );
		const float fZ			= ArrowEffects::GetZPos( m_pPlayerState, iCol, fYOffset );

		// XXX: Actor rotations use degrees, RageFastCos/Sin use radians. Convert here.
		const float fRotationY		= ArrowEffects::GetRotationY( m_pPlayerState, fYOffset ) * PI/180;

		// if we're rotating, we need to modify the X and Z coords for the outer edges.
		const float fRotOffsetX		= fFrameWidth/2 * RageFastCos(fRotationY);
		const float fRotOffsetZ		= fFrameWidth/2 * RageFastSin(fRotationY);
		const float fXLeft		= fX - fRotOffsetX;
		const float fXRight		= fX + fRotOffsetX;
		const float fZLeft		= fZ - fRotOffsetZ;
		const float fZRight		= fZ + fRotOffsetZ;

		const float fDistFromBodyBottom	= fYBodyBottom - fY;
		const float fDistFromBodyTop	= fY - fYBodyTop;
		float fTexCoordTop		= SCALE( bAnchorToBottom ? fDistFromBodyTop : fDistFromBodyBottom,    0, fFrameHeight, pRect->bottom, pRect->top );
		/* For very large hold notes, shift the texture coordinates to be near 0, so we
		 * don't send very large values to the renderer. */
		if( fY == fDrawYBodyTop ) // first
				fVertTexCoordOffset = floorf( fTexCoordTop );
		fTexCoordTop -= fVertTexCoordOffset;
		const float fTexCoordLeft		= pRect->left;
		const float fTexCoordRight		= pRect->right;
		const float	fAlpha				= ArrowGetAlphaOrGlow( bGlow, m_pPlayerState, iCol, fYOffset, fPercentFadeToFail, m_fYReverseOffsetPixels );
		const RageColor color			= RageColor(fColorScale,fColorScale,fColorScale,fAlpha);

		if( fAlpha > 0 )
			bAllAreTransparent = false;

		queue.v[0].p = RageVector3(fXLeft,  fY, fZLeft);	queue.v[0].c = color; queue.v[0].t = RageVector2(fTexCoordLeft,  fTexCoordTop);
		queue.v[1].p = RageVector3(fXRight, fY, fZRight);	queue.v[1].c = color; queue.v[1].t = RageVector2(fTexCoordRight, fTexCoordTop);
		queue.v+=2;
		if( queue.Free() < 2 )
		{
			/* The queue is full.  Render it, clear the buffer, and move back a step to
			 * start off the quad strip again. */
			if( !bAllAreTransparent )
				queue.Draw();
			queue.Init();
			bAllAreTransparent = true;
			fY -= fYStep;
		}
	}

	if( !bAllAreTransparent )
		queue.Draw();
}
static inline unsigned int IN_FROM_REG(u8 reg, int n)
{
	return SCALE(reg, nom_mv[n], 192);
}
Exemple #15
0
/* Apply the L-BFGS Strang's two-loop recursion to compute a search
   direction. */
static opk_status_t
apply(opk_vmlmn_t* opt, const opk_vector_t* g)
{
  double sty, yty;
  opk_index_t j, k;

  if (opt->mp < 1) {
    /* Will use the steepest descent direction. */
    return OPK_NOT_POSITIVE_DEFINITE;
  }
  COPY(opt->d, g);
  if (opt->method != OPK_VMLMN) {
    /* Apply the original L-BFGS Strang's two-loop recursion. */
    for (j = 1; j <= opt->mp; ++j) {
      k = slot(opt, j);
      if (RHO(k) > 0) {
        BETA(k) = RHO(k)*DOT(opt->d, S(k));
        UPDATE(opt->d, -BETA(k), Y(k));
      }
    }
    if (opt->gamma != 1) {
      /* Apply initial inverse Hessian approximation. */
      SCALE(opt->d, opt->gamma);
    }
    for (j = opt->mp; j >= 1; --j) {
      k = slot(opt, j);
      if (RHO(k) > 0) {
        UPDATE(opt->d, BETA(k) - RHO(k)*DOT(opt->d, Y(k)), S(k));
      }
    }
  } else {
    /* Apply L-BFGS Strang's two-loop recursion restricted to the subspace of
       free variables. */
    opt->gamma = 0;
    for (j = 1; j <= opt->mp; ++j) {
      k = slot(opt, j);
      sty = WDOT(Y(k), S(k));
      if (sty <= 0) {
        RHO(k) = 0;
        continue;
      }
      RHO(k) = 1/sty;
      BETA(k) = RHO(k)*WDOT(opt->d, S(k));
      UPDATE(opt->d, -BETA(k), Y(k));
      if (opt->gamma == 0) {
        yty = WDOT(Y(k), Y(k));
        if (yty > 0) {
          opt->gamma = sty/yty;
        }
      }
    }
    if (opt->gamma != 1) {
      if (opt->gamma <= 0) {
        /* Force using the steepest descent direction. */
        return OPK_NOT_POSITIVE_DEFINITE;
      }
      SCALE(opt->d, opt->gamma);
    }
    for (j = opt->mp; j >= 1; --j) {
      k = slot(opt, j);
      if (RHO(k) > 0) {
        UPDATE(opt->d, BETA(k) - RHO(k)*WDOT(opt->d, Y(k)), S(k));
      }
    }
  }

  if (opt->bounds != 0) {
    /* Enforce search direction to belong to the subset of the free
       variables. */
    opk_vproduct(opt->d, opt->w, opt->d);
  }

  return OPK_SUCCESS;
}
static inline u8 IN_TO_REG(unsigned long val, int n)
{
	return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255);
}
Exemple #17
0
void PaneDisplay::SetContent( PaneContents c )
{
	CString str = "?";	// fill this in
	float val = 0;	// fill this in

	const Song *pSong = GAMESTATE->m_pCurSong;
	const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber];
	const Course *pCourse = GAMESTATE->m_pCurCourse;
	const Trail *pTrail = GAMESTATE->m_pCurTrail[m_PlayerNumber];
	const Profile *pProfile = PROFILEMAN->GetProfile( m_PlayerNumber );
	bool bIsEdit = pSteps && pSteps->GetDifficulty() == DIFFICULTY_EDIT;

	if( (g_Contents[c].req&NEED_NOTES) && !pSteps )
		goto done;
	if( (g_Contents[c].req&NEED_COURSE) && !pTrail )
		goto done;
	if( (g_Contents[c].req&NEED_PROFILE) && !pProfile )
	{
		str = "N/A";
		goto done;
	}

	{
		RadarValues rv;

		if( g_Contents[c].req&NEED_NOTES )
			rv = pSteps->GetRadarValues();
		else if( g_Contents[c].req&NEED_COURSE )
			rv = pTrail->GetRadarValues();

		switch( c )
		{
		case COURSE_NUM_STEPS:
		case SONG_NUM_STEPS:				val = rv[RADAR_NUM_TAPS_AND_HOLDS]; break;
		case COURSE_JUMPS:
		case SONG_JUMPS:					val = rv[RADAR_NUM_JUMPS]; break;
		case COURSE_HOLDS:
		case SONG_HOLDS:					val = rv[RADAR_NUM_HOLDS]; break;
		case COURSE_MINES:
		case SONG_MINES:					val = rv[RADAR_NUM_MINES]; break;
		case COURSE_HANDS:
		case SONG_HANDS:					val = rv[RADAR_NUM_HANDS]; break;
		case SONG_DIFFICULTY_RADAR_STREAM:	val = rv[RADAR_STREAM]; break;
		case SONG_DIFFICULTY_RADAR_VOLTAGE:	val = rv[RADAR_VOLTAGE]; break;
		case SONG_DIFFICULTY_RADAR_AIR:		val = rv[RADAR_AIR]; break;
		case SONG_DIFFICULTY_RADAR_FREEZE:	val = rv[RADAR_FREEZE]; break;
		case SONG_DIFFICULTY_RADAR_CHAOS:	val = rv[RADAR_CHAOS]; break;
		case SONG_PROFILE_HIGH_SCORE:
			val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsHighScoreList(pSong,pSteps).GetTopScore().fPercentDP;
			break;
		case SONG_PROFILE_NUM_PLAYS:
			val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsNumTimesPlayed(pSong,pSteps);
			break;

		case SONG_MACHINE_HIGH_NAME: /* set val for color */
		case SONG_MACHINE_HIGH_SCORE:
			CHECKPOINT;
			if( bIsEdit )	
				goto done;	// no machine scores for edits
			val = 100.0f * PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps).GetTopScore().fPercentDP;
			break;

		case SONG_MACHINE_RANK:
			{
			const vector<Song*> best = SONGMAN->GetBestSongs( PROFILE_SLOT_MACHINE );
			val = (float) FindIndex( best.begin(), best.end(), pSong );
			val += 1;
			break;
			}

		case SONG_PROFILE_RANK:
			{
			const vector<Song*> best = SONGMAN->GetBestSongs( PlayerMemCard(m_PlayerNumber) );
			val = (float) FindIndex( best.begin(), best.end(), pSong );
			val += 1;
			break;
			}

		case COURSE_MACHINE_HIGH_NAME: /* set val for color */
		case COURSE_MACHINE_HIGH_SCORE:
			val = 100.0f * PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().fPercentDP;
			break;

		case COURSE_MACHINE_NUM_PLAYS:
			val = (float) PROFILEMAN->GetMachineProfile()->GetCourseNumTimesPlayed( pCourse );
			break;

		case COURSE_MACHINE_RANK:
			{
			const vector<Course*> best = SONGMAN->GetBestCourses( PROFILE_SLOT_MACHINE );
			val = (float) FindIndex( best.begin(), best.end(), pCourse );
			val += 1;
			}
			break;

		case COURSE_PROFILE_HIGH_SCORE:
			val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().fPercentDP;
			break;
		case COURSE_PROFILE_NUM_PLAYS:
			val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseNumTimesPlayed( pCourse );
			break;

		case COURSE_PROFILE_RANK:
			const vector<Course*> best = SONGMAN->GetBestCourses( PlayerMemCard(m_PlayerNumber) );
			val = (float) FindIndex( best.begin(), best.end(), pCourse );
			val += 1;
			break;
		};

		if( val == RADAR_VAL_UNKNOWN )
			goto done;

		/* Scale, round, clamp, etc. for floats: */
		switch( c )
		{
		case SONG_DIFFICULTY_RADAR_STREAM:
		case SONG_DIFFICULTY_RADAR_VOLTAGE:
		case SONG_DIFFICULTY_RADAR_AIR:
		case SONG_DIFFICULTY_RADAR_FREEZE:
		case SONG_DIFFICULTY_RADAR_CHAOS:
			val = roundf( SCALE( val, 0, 1, 0, 10 ) );
			val = clamp( val, 0, 10 );
			str = ssprintf( "%.0f", val );
			break;
		}

		switch( c )
		{
		case SONG_MACHINE_HIGH_NAME:
			str = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps).GetTopScore().sName;
			break;
		case COURSE_MACHINE_HIGH_NAME:

			str = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().sName;
			break;

		case SONG_MACHINE_HIGH_SCORE:
		case COURSE_MACHINE_HIGH_SCORE:
		case SONG_PROFILE_HIGH_SCORE:
		case COURSE_PROFILE_HIGH_SCORE:
			str = ssprintf( "%.2f%%", val );
			break;
		case SONG_NUM_STEPS:
		case SONG_JUMPS:
		case SONG_HOLDS:
		case SONG_MINES:
		case SONG_HANDS:
		case COURSE_NUM_STEPS:
		case COURSE_JUMPS:
		case COURSE_HOLDS:
		case COURSE_MINES:
		case COURSE_HANDS:
		case SONG_MACHINE_NUM_PLAYS:
		case COURSE_MACHINE_NUM_PLAYS:
		case SONG_PROFILE_NUM_PLAYS:
		case COURSE_PROFILE_NUM_PLAYS:
		case SONG_MACHINE_RANK:
		case COURSE_MACHINE_RANK:
		case SONG_PROFILE_RANK:
		case COURSE_PROFILE_RANK:
			str = ssprintf( "%.0f", val );
		}
	}


done:
	m_textContents[c].SetText( str );

	const int num = NUM_ITEM_COLORS( g_Contents[c].name );
	for( int p = 0; p < num; ++p )
	{
		const CString metric = ITEM_COLOR(g_Contents[c].name, p);
		CStringArray spec;
		split( metric, ";", spec );
		if( spec.size() < 2 )
			RageException::Throw( "Metric '%s' malformed", metric.c_str() );

		const float n = strtof( spec[0], NULL );
		if( val >= n )
			continue;
		spec.erase( spec.begin(), spec.begin()+1 );

		m_textContents[c].Command( join(";", spec) );
		break;
	}
}
GLOBAL Int UMF_solve
(
    Int sys,
    const Int Ap [ ],
    const Int Ai [ ],
    const double Ax [ ],
    double Xx [ ],
    const double Bx [ ],
#ifdef COMPLEX
    const double Az [ ],
    double Xz [ ],
    const double Bz [ ],
#endif
    NumericType *Numeric,
    Int irstep,
    double Info [UMFPACK_INFO],
    Int Pattern [ ],		/* size n */
    double SolveWork [ ]	/* if irstep>0 real:  size 5*n.  complex:10*n */
				/* otherwise   real:  size   n.  complex: 4*n */
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Entry axx, wi, xj, zi, xi, aij, bi ;
    double omega [3], d, z2i, yi, flops ;
    Entry *W, *Z, *S, *X ;
    double *Z2, *Y, *B2, *Rs ;
    Int *Rperm, *Cperm, i, n, p, step, j, nz, status, p2, do_scale ;
#ifdef COMPLEX
    Int AXsplit ;
    Int Bsplit ;
#endif
#ifndef NRECIPROCAL
    Int do_recip = Numeric->do_recip ;
#endif

    /* ---------------------------------------------------------------------- */
    /* initializations */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    UMF_dump_lu (Numeric) ;
    ASSERT (Numeric && Xx && Bx && Pattern && SolveWork && Info) ;
#endif

    nz = 0 ;
    omega [0] = 0. ;
    omega [1] = 0. ;
    omega [2] = 0. ;
    Rperm = Numeric->Rperm ;
    Cperm = Numeric->Cperm ;
    Rs = Numeric->Rs ;		/* row scale factors */
    do_scale = (Rs != (double *) NULL) ;
    flops = 0 ;
    Info [UMFPACK_SOLVE_FLOPS] = 0 ;
    Info [UMFPACK_IR_TAKEN] = 0 ;
    Info [UMFPACK_IR_ATTEMPTED] = 0 ;

    /* UMFPACK_solve does not call this routine if A is rectangular */
    ASSERT (Numeric->n_row == Numeric->n_col) ;
    n = Numeric->n_row ;
    if (Numeric->nnzpiv < n
	|| SCALAR_IS_ZERO (Numeric->rcond) || SCALAR_IS_NAN (Numeric->rcond))
    {
	/* Note that systems involving just L return UMFPACK_OK, even if */
	/* A is singular (L is always has a unit diagonal). */
	DEBUGm4 (("Note, matrix is singular in umf_solve\n")) ;
	status = UMFPACK_WARNING_singular_matrix ;
	irstep = 0 ;
    }
    else
    {
	status = UMFPACK_OK ;
    }
    irstep = MAX (0, irstep) ;			/* make sure irstep is >= 0 */

    W = (Entry *) SolveWork ;			/* Entry W [0..n-1] */

    Z = (Entry *) NULL ;	/* unused if no iterative refinement */
    S = (Entry *) NULL ;
    Y = (double *) NULL ;
    Z2 = (double *) NULL ;
    B2 = (double *) NULL ;

#ifdef COMPLEX
    if (irstep > 0)
    {
	if (!Ap || !Ai || !Ax)
	{
	    return (UMFPACK_ERROR_argument_missing) ;
	}
	/* A, B, and X in split format if Az, Bz, and Xz present */
	AXsplit = SPLIT (Az) || SPLIT(Xz);
	Z = (Entry *) (SolveWork + 4*n) ;	/* Entry Z [0..n-1] */
	S = (Entry *) (SolveWork + 6*n) ;	/* Entry S [0..n-1] */
	Y = (double *) (SolveWork + 8*n) ;	/* double Y [0..n-1] */
	B2 = (double *) (SolveWork + 9*n) ;	/* double B2 [0..n-1] */
	Z2 = (double *) Z ;		/* double Z2 [0..n-1], equiv. to Z */
    }
    else
    {
      /* A is ignored, only  look at X for split/packed cases */
      AXsplit = SPLIT(Xz);
    }
    Bsplit = SPLIT (Bz);

    if (AXsplit)
    {
	X = (Entry *) (SolveWork + 2*n) ;	/* Entry X [0..n-1] */
    }
    else
    {
	X = (Entry *) Xx ;			/* Entry X [0..n-1] */
    }
#else
    X = (Entry *) Xx ;				/* Entry X [0..n-1] */
    if (irstep > 0)
    {
	if (!Ap || !Ai || !Ax)
	{
	    return (UMFPACK_ERROR_argument_missing) ;
	}
	Z = (Entry *) (SolveWork + n) ;		/* Entry Z [0..n-1] */
	S = (Entry *) (SolveWork + 2*n) ;	/* Entry S [0..n-1] */
	Y = (double *) (SolveWork + 3*n) ;	/* double Y [0..n-1] */
	B2 = (double *) (SolveWork + 4*n) ;	/* double B2 [0..n-1] */
	Z2 = (double *) Z ;		/* double Z2 [0..n-1], equiv. to Z */
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* determine which system to solve */
    /* ---------------------------------------------------------------------- */

    if (sys == UMFPACK_A)
    {

	/* ------------------------------------------------------------------ */
	/* solve A x = b with optional iterative refinement */
	/* ------------------------------------------------------------------ */

	if (irstep > 0)
	{

	    /* -------------------------------------------------------------- */
	    /* using iterative refinement:  compute Y and B2 */
	    /* -------------------------------------------------------------- */

	    nz = Ap [n] ;
	    Info [UMFPACK_NZ] = nz ;

	    /* A is stored by column */
	    /* Y (i) = ||R A_i||, 1-norm of row i of R A */
	    for (i = 0 ; i < n ; i++)
	    {
		Y [i] = 0. ;
	    }
	    flops += (ABS_FLOPS + 1) * nz ;
	    p2 = Ap [n] ;
	    for (p = 0 ; p < p2 ; p++)
	    {
		/* Y [Ai [p]] += ABS (Ax [p]) ; */
	        ASSIGN (aij, Ax, Az, p, AXsplit) ;
		ABS (d, aij) ;
		Y [Ai [p]] += d ;
	    }

	    /* B2 = abs (B) */
	    flops += ABS_FLOPS * n ;
	    for (i = 0 ; i < n ; i++)
	    {
		/* B2 [i] = ABS (B [i]) ; */
		ASSIGN (bi, Bx, Bz, i, Bsplit) ;
		ABS (B2 [i], bi) ;
	    }

	    /* scale Y and B2. */
	    if (do_scale)
	    {
		/* Y = R Y */
		/* B2 = R B2 */
#ifndef NRECIPROCAL
		if (do_recip)
		{
		    /* multiply by the scale factors */
		    for (i = 0 ; i < n ; i++)
		    {
			Y [i]  *= Rs [i] ;
			B2 [i] *= Rs [i] ;
		    }
		}
		else
#endif
		{
		    /* divide by the scale factors */
		    for (i = 0 ; i < n ; i++)
		    {
			Y [i]  /= Rs [i] ;
			B2 [i] /= Rs [i] ;
		    }
		}

		flops += 2 * n ;
	    }

	}

	for (step = 0 ; step <= irstep ; step++)
	{

	    /* -------------------------------------------------------------- */
	    /* Solve A x = b (step 0): */
	    /*  x = Q (U \ (L \ (P R b))) */
	    /* and then perform iterative refinement (step > 0): */
	    /*  x = x + Q (U \ (L \ (P R (b - A x)))) */
	    /* -------------------------------------------------------------- */

	    if (step == 0)
	    {
		if (do_scale)
		{
		    /* W = P R b, using X as workspace, since Z is not
		     * allocated if irstep = 0. */
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
			    SCALE (X [i], Rs [i]) ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
			    SCALE_DIV (X [i], Rs [i]) ;
			}
		    }
		    flops += SCALE_FLOPS * n ;
		    for (i = 0 ; i < n ; i++)
		    {
			W [i] = X [Rperm [i]] ;
		    }
		}
		else
		{
		    /* W = P b, since the row scaling R = I */
		    for (i = 0 ; i < n ; i++)
		    {
			/* W [i] = B [Rperm [i]] ; */
			ASSIGN (W [i], Bx, Bz, Rperm [i], Bsplit) ;
		    }
		}
	    }
	    else
	    {
		for (i = 0 ; i < n ; i++)
		{
		    /* Z [i] = B [i] ; */
		    ASSIGN (Z [i], Bx, Bz, i, Bsplit) ;
		}
		flops += MULTSUB_FLOPS * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    xi = X [i] ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* Z [Ai [p]] -= Ax [p] * xi ; */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			MULT_SUB (Z [Ai [p]], aij, xi) ;
		    }
		}
		/* scale, Z = R Z */
		if (do_scale)
		{
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE (Z [i], Rs [i]) ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE_DIV (Z [i], Rs [i]) ;
			}
		    }
		    flops += SCALE_FLOPS * n ;
		}
		for (i = 0 ; i < n ; i++)
		{
		    W [i] = Z [Rperm [i]] ;
		}
	    }

	    flops += UMF_lsolve (Numeric, W, Pattern) ;
	    flops += UMF_usolve (Numeric, W, Pattern) ;

	    if (step == 0)
	    {
		for (i = 0 ; i < n ; i++)
		{
		    X [Cperm [i]] = W [i] ;
		}
	    }
	    else
	    {
		flops += ASSEMBLE_FLOPS * n ;
		for (i = 0 ; i < n ; i++)
		{
		    /* X [Cperm [i]] += W [i] ; */
		    ASSEMBLE (X [Cperm [i]], W [i]) ;
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* sparse backward error estimate */
	    /* -------------------------------------------------------------- */

	    if (irstep > 0)
	    {

		/* ---------------------------------------------------------- */
		/* A is stored by column */
		/* W (i) = R (b - A x)_i, residual */
		/* Z2 (i) = R (|A||x|)_i */
		/* ---------------------------------------------------------- */

		for (i = 0 ; i < n ; i++)
		{
		    /* W [i] = B [i] ; */
		    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
		    Z2 [i] = 0. ;
		}
		flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ;
		for (j = 0 ; j < n ; j++)
		{
		    xj = X [j] ;
		    p2 = Ap [j+1] ;
		    for (p = Ap [j] ; p < p2 ; p++)
		    {
			i = Ai [p] ;

			/* axx = Ax [p] * xj ; */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			MULT (axx, aij, xj) ;

			/* W [i] -= axx ; */
			DECREMENT (W [i], axx) ;

			/* Z2 [i] += ABS (axx) ; */
			ABS (d, axx) ;
			Z2 [i] += d ;
		    }
		}

		/* scale W and Z2 */
		if (do_scale)
		{
		    /* Z2 = R Z2 */
		    /* W = R W */
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE (W [i], Rs [i]) ;
			    Z2 [i] *= Rs [i] ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE_DIV (W [i], Rs [i]) ;
			    Z2 [i] /= Rs [i] ;
			}
		    }
		    flops += (SCALE_FLOPS + 1) * n ;
		}

		flops += (2*ABS_FLOPS + 5) * n ;
		if (do_step (omega, step, B2, X, W, Y, Z2, S, n, Info))
		{
		    /* iterative refinement is done */
		    break ;
		}

	    }

	}

    }
    else if (sys == UMFPACK_At)
    {

	/* ------------------------------------------------------------------ */
	/* solve A' x = b with optional iterative refinement */
	/* ------------------------------------------------------------------ */

	/* A' is the complex conjugate transpose */

	if (irstep > 0)
	{

	    /* -------------------------------------------------------------- */
	    /* using iterative refinement:  compute Y */
	    /* -------------------------------------------------------------- */

	    nz = Ap [n] ;
	    Info [UMFPACK_NZ] = nz ;

	    /* A' is stored by row */
	    /* Y (i) = ||(A' R)_i||, 1-norm of row i of A' R */

	    if (do_scale)
	    {
		flops += (ABS_FLOPS + 2) * nz ;
#ifndef NRECIPROCAL
		if (do_recip)
		{
		    /* multiply by the scale factors */
		    for (i = 0 ; i < n ; i++)
		    {
			yi = 0. ;
			p2 = Ap [i+1] ;
			for (p = Ap [i] ; p < p2 ; p++)
			{
			    /* yi += ABS (Ax [p]) * Rs [Ai [p]] ; */
			    /* note that abs (aij) is the same as
			     * abs (conj (aij)) */
			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
			    ABS (d, aij) ;
			    yi += (d * Rs [Ai [p]]) ;
			}
			Y [i] = yi ;
		    }
		}
		else
#endif
		{
		    /* divide by the scale factors */
		    for (i = 0 ; i < n ; i++)
		    {
			yi = 0. ;
			p2 = Ap [i+1] ;
			for (p = Ap [i] ; p < p2 ; p++)
			{
			    /* yi += ABS (Ax [p]) / Rs [Ai [p]] ; */
			    /* note that abs (aij) is the same as
			     * abs (conj (aij)) */
			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
			    ABS (d, aij) ;
			    yi += (d / Rs [Ai [p]]) ;
			}
			Y [i] = yi ;
		    }
		}
	    }
	    else
	    {
		/* no scaling */
		flops += (ABS_FLOPS + 1) * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    yi = 0. ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* yi += ABS (Ax [p]) ; */
			/* note that abs (aij) is the same as
			 * abs (conj (aij)) */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			ABS (d, aij) ;
			yi += d ;
		    }
		    Y [i] = yi ;
		}
	    }

	    /* B2 = abs (B) */
	    for (i = 0 ; i < n ; i++)
	    {
		/* B2 [i] = ABS (B [i]) ; */
		ASSIGN (bi, Bx, Bz, i, Bsplit) ;
		ABS (B2 [i], bi) ;
	    }

	}

	for (step = 0 ; step <= irstep ; step++)
	{

	    /* -------------------------------------------------------------- */
	    /* Solve A' x = b (step 0): */
	    /*	x = R P' (L' \ (U' \ (Q' b))) */
	    /* and then perform iterative refinement (step > 0): */
	    /*	x = x + R P' (L' \ (U' \ (Q' (b - A' x)))) */
	    /* -------------------------------------------------------------- */

	    if (step == 0)
	    {
		/* W = Q' b */
		for (i = 0 ; i < n ; i++)
		{
		    /* W [i] = B [Cperm [i]] ; */
		    ASSIGN (W [i], Bx, Bz, Cperm [i], Bsplit) ;
		}
	    }
	    else
	    {
		/* Z = b - A' x */
		for (i = 0 ; i < n ; i++)
		{
		    /* Z [i] = B [i] ; */
		    ASSIGN (Z [i], Bx, Bz, i, Bsplit) ;
		}
		flops += MULTSUB_FLOPS * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    zi = Z [i] ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* zi -= conjugate (Ax [p]) * X [Ai [p]] ; */
			ASSIGN (aij, Ax, Az, p, Bsplit) ;
			MULT_SUB_CONJ (zi, X [Ai [p]], aij) ;
		    }
		    Z [i] = zi ;
		}
		/* W = Q' Z */
		for (i = 0 ; i < n ; i++)
		{
		    W [i] = Z [Cperm [i]] ;
		}
	    }

	    flops += UMF_uhsolve (Numeric, W, Pattern) ;
	    flops += UMF_lhsolve (Numeric, W, Pattern) ;

	    if (step == 0)
	    {

		/* X = R P' W */
		/* do not use Z, since it isn't allocated if irstep = 0 */

		/* X = P' W */
		for (i = 0 ; i < n ; i++)
		{
		    X [Rperm [i]] = W [i] ;
		}
		if (do_scale)
		{
		    /* X = R X */
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE (X [i], Rs [i]) ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE_DIV (X [i], Rs [i]) ;
			}
		    }
		    flops += SCALE_FLOPS * n ;
		}

	    }
	    else
	    {

		/* Z = P' W */
		for (i = 0 ; i < n ; i++)
		{
		    Z [Rperm [i]] = W [i] ;
		}
		if (do_scale)
		{
		    /* Z = R Z */
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE (Z [i], Rs [i]) ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE_DIV (Z [i], Rs [i]) ;
			}
		    }
		    flops += SCALE_FLOPS * n ;
		}

		flops += ASSEMBLE_FLOPS * n ;
		/* X += Z */
		for (i = 0 ; i < n ; i++)
		{
		    /* X [i] += Z [i] ; was +=W[i] in v4.3, which is wrong */
		    ASSEMBLE (X [i], Z [i]) ;	/* bug fix, v4.3.1 */
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* sparse backward error estimate */
	    /* -------------------------------------------------------------- */

	    if (irstep > 0)
	    {

		/* ---------------------------------------------------------- */
		/* A' is stored by row */
		/* W (i) = (b - A' x)_i, residual */
		/* Z2 (i) = (|A'||x|)_i */
		/* ---------------------------------------------------------- */

		flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    /* wi = B [i] ; */
		    ASSIGN (wi, Bx, Bz, i, Bsplit) ;
		    z2i = 0. ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* axx = conjugate (Ax [p]) * X [Ai [p]] ; */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			MULT_CONJ (axx, X [Ai [p]], aij) ;

			/* wi -= axx ; */
			DECREMENT (wi, axx) ;

			/* z2i += ABS (axx) ; */
			ABS (d, axx) ;
			z2i += d ;
		    }
		    W [i] = wi ;
		    Z2 [i] = z2i ;
		}

		flops += (2*ABS_FLOPS + 5) * n ;
		if (do_step (omega, step, B2, X, W, Y, Z2, S, n, Info))
		{
		    /* iterative refinement is done */
		    break ;
		}

	    }

	}

    }
    else if (sys == UMFPACK_Aat)
    {

	/* ------------------------------------------------------------------ */
	/* solve A.' x = b with optional iterative refinement */
	/* ------------------------------------------------------------------ */

	/* A' is the array transpose */

	if (irstep > 0)
	{

	    /* -------------------------------------------------------------- */
	    /* using iterative refinement:  compute Y */
	    /* -------------------------------------------------------------- */

	    nz = Ap [n] ;
	    Info [UMFPACK_NZ] = nz ;

	    /* A.' is stored by row */
	    /* Y (i) = ||(A.' R)_i||, 1-norm of row i of A.' R */

	    if (do_scale)
	    {
		flops += (ABS_FLOPS + 2) * nz ;
#ifndef NRECIPROCAL
		if (do_recip)
		{
		    /* multiply by the scale factors */
		    for (i = 0 ; i < n ; i++)
		    {
			yi = 0. ;
			p2 = Ap [i+1] ;
			for (p = Ap [i] ; p < p2 ; p++)
			{
			    /* yi += ABS (Ax [p]) * Rs [Ai [p]] ; */
			    /* note that A.' is the array transpose,
			     * so no conjugate */
			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
			    ABS (d, aij) ;
			    yi += (d * Rs [Ai [p]]) ;
			}
			Y [i] = yi ;
		    }
		}
		else
#endif
		{
		    /* divide by the scale factors */
		    for (i = 0 ; i < n ; i++)
		    {
			yi = 0. ;
			p2 = Ap [i+1] ;
			for (p = Ap [i] ; p < p2 ; p++)
			{
			    /* yi += ABS (Ax [p]) / Rs [Ai [p]] ; */
			    /* note that A.' is the array transpose,
			     * so no conjugate */
			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
			    ABS (d, aij) ;
			    yi += (d / Rs [Ai [p]]) ;
			}
			Y [i] = yi ;
		    }
		}
	    }
	    else
	    {
		/* no scaling */
		flops += (ABS_FLOPS + 1) * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    yi = 0. ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* yi += ABS (Ax [p]) */
			/* note that A.' is the array transpose,
			 * so no conjugate */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			ABS (d, aij) ;
			yi += d ;
		    }
		    Y [i] = yi ;
		}
	    }

	    /* B2 = abs (B) */
	    for (i = 0 ; i < n ; i++)
	    {
		/* B2 [i] = ABS (B [i]) ; */
		ASSIGN (bi, Bx, Bz, i, Bsplit) ;
		ABS (B2 [i], bi) ;
	    }

	}

	for (step = 0 ; step <= irstep ; step++)
	{

	    /* -------------------------------------------------------------- */
	    /* Solve A.' x = b (step 0): */
	    /*	x = R P' (L.' \ (U.' \ (Q' b))) */
	    /* and then perform iterative refinement (step > 0): */
	    /*	x = x + R P' (L.' \ (U.' \ (Q' (b - A.' x)))) */
	    /* -------------------------------------------------------------- */

	    if (step == 0)
	    {
		/* W = Q' b */
		for (i = 0 ; i < n ; i++)
		{
		    /* W [i] = B [Cperm [i]] ; */
		    ASSIGN (W [i], Bx, Bz, Cperm [i], Bsplit) ;
		}
	    }
	    else
	    {
		/* Z = b - A.' x */
		for (i = 0 ; i < n ; i++)
		{
		    /* Z [i] = B [i] ; */
		    ASSIGN (Z [i], Bx, Bz, i, Bsplit) ;
		}
		flops += MULTSUB_FLOPS * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    zi = Z [i] ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* zi -= Ax [p] * X [Ai [p]] ; */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			MULT_SUB (zi, aij, X [Ai [p]]) ;
		    }
		    Z [i] = zi ;
		}
		/* W = Q' Z */
		for (i = 0 ; i < n ; i++)
		{
		    W [i] = Z [Cperm [i]] ;
		}
	    }

	    flops += UMF_utsolve (Numeric, W, Pattern) ;
	    flops += UMF_ltsolve (Numeric, W, Pattern) ;

	    if (step == 0)
	    {

		/* X = R P' W */
		/* do not use Z, since it isn't allocated if irstep = 0 */

		/* X = P' W */
		for (i = 0 ; i < n ; i++)
		{
		    X [Rperm [i]] = W [i] ;
		}
		if (do_scale)
		{
		    /* X = R X */
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE (X [i], Rs [i]) ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE_DIV (X [i], Rs [i]) ;
			}
		    }
		    flops += SCALE_FLOPS * n ;
		}

	    }
	    else
	    {

		/* Z = P' W */
		for (i = 0 ; i < n ; i++)
		{
		    Z [Rperm [i]] = W [i] ;
		}
		if (do_scale)
		{
		    /* Z = R Z */
#ifndef NRECIPROCAL
		    if (do_recip)
		    {
			/* multiply by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE (Z [i], Rs [i]) ;
			}
		    }
		    else
#endif
		    {
			/* divide by the scale factors */
			for (i = 0 ; i < n ; i++)
			{
			    SCALE_DIV (Z [i], Rs [i]) ;
			}
		    }
		    flops += SCALE_FLOPS * n ;
		}

		flops += ASSEMBLE_FLOPS * n ;
		/* X += Z */
		for (i = 0 ; i < n ; i++)
		{
		    /* X [i] += Z [i] ; was +=W[i] in v4.3, which is wrong */
		    ASSEMBLE (X [i], Z [i]) ;	/* bug fix, v4.3.1 */
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* sparse backward error estimate */
	    /* -------------------------------------------------------------- */

	    if (irstep > 0)
	    {

		/* ---------------------------------------------------------- */
		/* A.' is stored by row */
		/* W (i) = (b - A.' x)_i, residual */
		/* Z (i) = (|A.'||x|)_i */
		/* ---------------------------------------------------------- */

		flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ;
		for (i = 0 ; i < n ; i++)
		{
		    /* wi = B [i] ; */
		    ASSIGN (wi, Bx, Bz, i, Bsplit) ;
		    z2i = 0. ;
		    p2 = Ap [i+1] ;
		    for (p = Ap [i] ; p < p2 ; p++)
		    {
			/* axx = Ax [p] * X [Ai [p]] ; */
			ASSIGN (aij, Ax, Az, p, AXsplit) ;
			MULT (axx, aij, X [Ai [p]]) ;

			/* wi -= axx ; */
			DECREMENT (wi, axx) ;

			/* z2i += ABS (axx) ; */
			ABS (d, axx) ;
			z2i += d ;
		    }
		    W [i] = wi ;
		    Z2 [i] = z2i ;
		}

		flops += (2*ABS_FLOPS + 5) * n ;
		if (do_step (omega, step, B2, X, W, Y, Z2, S, n, Info))
		{
		    /* iterative refinement is done */
		    break ;
		}

	    }

	}

    }
    else if (sys == UMFPACK_Pt_L)
    {

	/* ------------------------------------------------------------------ */
	/* Solve P'Lx=b:  x = L \ Pb */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [Rperm [i]] ; */
	    ASSIGN (X [i], Bx, Bz, Rperm [i], Bsplit) ;
	}
	flops = UMF_lsolve (Numeric, X, Pattern) ;
	status = UMFPACK_OK ;

    }
    else if (sys == UMFPACK_L)
    {

	/* ------------------------------------------------------------------ */
	/* Solve Lx=b:  x = L \ b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [i] ; */
	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_lsolve (Numeric, X, Pattern) ;
	status = UMFPACK_OK ;

    }
    else if (sys == UMFPACK_Lt_P)
    {

	/* ------------------------------------------------------------------ */
	/* Solve L'Px=b:  x = P' (L' \ b) */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* W [i] = B [i] ; */
	    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_lhsolve (Numeric, W, Pattern) ;
	for (i = 0 ; i < n ; i++)
	{
	    X [Rperm [i]] = W [i] ;
	}
	status = UMFPACK_OK ;

    }
    else if (sys == UMFPACK_Lat_P)
    {

	/* ------------------------------------------------------------------ */
	/* Solve L.'Px=b:  x = P' (L.' \ b) */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* W [i] = B [i] ; */
	    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_ltsolve (Numeric, W, Pattern) ;
	for (i = 0 ; i < n ; i++)
	{
	    X [Rperm [i]] = W [i] ;
	}
	status = UMFPACK_OK ;

    }
    else if (sys == UMFPACK_Lt)
    {

	/* ------------------------------------------------------------------ */
	/* Solve L'x=b:  x = L' \ b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [i] ; */
	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_lhsolve (Numeric, X, Pattern) ;
	status = UMFPACK_OK ;

    }
    else if (sys == UMFPACK_Lat)
    {

	/* ------------------------------------------------------------------ */
	/* Solve L.'x=b:  x = L.' \ b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [i] ; */
	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_ltsolve (Numeric, X, Pattern) ;
	status = UMFPACK_OK ;

    }
    else if (sys == UMFPACK_U_Qt)
    {

	/* ------------------------------------------------------------------ */
	/* Solve UQ'x=b:  x = Q (U \ b) */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* W [i] = B [i] ; */
	    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_usolve (Numeric, W, Pattern) ;
	for (i = 0 ; i < n ; i++)
	{
	    X [Cperm [i]] = W [i] ;
	}

    }
    else if (sys == UMFPACK_U)
    {

	/* ------------------------------------------------------------------ */
	/* Solve Ux=b:  x = U \ b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [i] ; */
	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_usolve (Numeric, X, Pattern) ;

    }
    else if (sys == UMFPACK_Q_Ut)
    {

	/* ------------------------------------------------------------------ */
	/* Solve QU'x=b:  x = U' \ Q'b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [Cperm [i]] ; */
	    ASSIGN (X [i], Bx, Bz, Cperm [i], Bsplit) ;
	}
	flops = UMF_uhsolve (Numeric, X, Pattern) ;

    }
    else if (sys == UMFPACK_Q_Uat)
    {

	/* ------------------------------------------------------------------ */
	/* Solve QU.'x=b:  x = U.' \ Q'b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [Cperm [i]] ; */
	    ASSIGN (X [i], Bx, Bz, Cperm [i], Bsplit) ;
	}
	flops = UMF_utsolve (Numeric, X, Pattern) ;

    }
    else if (sys == UMFPACK_Ut)
    {

	/* ------------------------------------------------------------------ */
	/* Solve U'x=b:  x = U' \ b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [i] ; */
	  ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_uhsolve (Numeric, X, Pattern) ;

    }
    else if (sys == UMFPACK_Uat)
    {

	/* ------------------------------------------------------------------ */
	/* Solve U'x=b:  x = U' \ b */
	/* ------------------------------------------------------------------ */

	for (i = 0 ; i < n ; i++)
	{
	    /* X [i] = B [i] ; */
	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
	}
	flops = UMF_utsolve (Numeric, X, Pattern) ;

    }
    else
    {
	return (UMFPACK_ERROR_invalid_system) ;
    }

#ifdef COMPLEX
    /* copy the solution back, from Entry X [ ] to double Xx [ ] and Xz [ ] */
    if (AXsplit)
    {
	for (i = 0 ; i < n ; i++)
	{
	    Xx [i] = REAL_COMPONENT (X [i]) ;
	    Xz [i] = IMAG_COMPONENT (X [i]) ;
	}
    }
#endif

    /* return UMFPACK_OK, or UMFPACK_WARNING_singular_matrix */
    /* Note that systems involving just L will return UMFPACK_OK */
    Info [UMFPACK_SOLVE_FLOPS] = flops ;
    return (status) ;
}
Exemple #19
0
void VCSlider::writeDMXLevel(MasterTimer* timer, UniverseArray* universes)
{
    Q_UNUSED(timer);

    m_levelValueMutex.lock();

    uchar modLevel = m_levelValue;

    int r = 0, g = 0, b = 0, c = 0, m = 0, y = 0;
    if (m_cngType == ClickAndGoWidget::RGB)
    {
        float f = 0;
        if (m_slider)
            f = SCALE(float(m_levelValue), float(m_slider->minimum()),
                      float(m_slider->maximum()), float(0), float(200));
        if ((uchar)f != 0)
        {
            QColor modColor = m_cngRGBvalue.lighter((uchar)f);
            r = modColor.red();
            g = modColor.green();
            b = modColor.blue();
        }
    }
    else if (m_cngType == ClickAndGoWidget::CMY)
    {
        float f = 0;
        if (m_slider)
            f = SCALE(float(m_levelValue), float(m_slider->minimum()),
                      float(m_slider->maximum()), float(0), float(200));
        if ((uchar)f != 0)
        {
            QColor modColor = m_cngRGBvalue.lighter((uchar)f);
            c = modColor.cyan();
            m = modColor.magenta();
            y = modColor.yellow();
        }
    }

    QListIterator <LevelChannel> it(m_levelChannels);
    while (it.hasNext() == true)
    {
        LevelChannel lch(it.next());
        Fixture* fxi = m_doc->fixture(lch.fixture);
        if (fxi != NULL)
        {
            const QLCChannel* qlcch = fxi->channel(lch.channel);
            if (qlcch == NULL)
                continue;

            if (qlcch->group() != QLCChannel::Intensity &&
                m_levelValueChanged == false)
            {
                /* Value has not changed and this is not an intensity channel.
                   LTP in effect. */
                continue;
            }
            if (qlcch->group() == QLCChannel::Intensity)
            {
                if (m_cngType == ClickAndGoWidget::RGB)
                {
                    if (qlcch->colour() == QLCChannel::Red)
                        modLevel = (uchar)r;
                    else if (qlcch->colour() == QLCChannel::Green)
                        modLevel = (uchar)g;
                    else if (qlcch->colour() == QLCChannel::Blue)
                        modLevel = (uchar)b;
                }
                else if (m_cngType == ClickAndGoWidget::CMY)
                {
                    if (qlcch->colour() == QLCChannel::Cyan)
                        modLevel = (uchar)c;
                    else if (qlcch->colour() == QLCChannel::Magenta)
                        modLevel = (uchar)m;
                    else if (qlcch->colour() == QLCChannel::Yellow)
                        modLevel = (uchar)y;
                }
            }

            quint32 dmx_ch = fxi->channelAddress(lch.channel);
            universes->write(dmx_ch, modLevel, qlcch->group());
        }
    }
    m_levelValueChanged = false;
    m_levelValueMutex.unlock();
}