#include "blaswrap.h"
/*  -- translated by f2c (version 19990503).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/

#include "f2c.h"

/* Table of constant values */

static complex c_b1 = {0.f,0.f};
static complex c_b2 = {1.f,0.f};

/* Subroutine */ int cget54_(integer *n, complex *a, integer *lda, complex *b,
	 integer *ldb, complex *s, integer *lds, complex *t, integer *ldt, 
	complex *u, integer *ldu, complex *v, integer *ldv, complex *work, 
	real *result)
{
    /* System generated locals */
    integer a_dim1, a_offset, b_dim1, b_offset, s_dim1, s_offset, t_dim1, 
	    t_offset, u_dim1, u_offset, v_dim1, v_offset, i__1;
    real r__1, r__2;
    complex q__1;

    /* Local variables */
    static real unfl;
    extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, 
	    integer *, complex *, complex *, integer *, complex *, integer *, 
	    complex *, complex *, integer *);
    static real wnorm;
    extern doublereal clange_(char *, integer *, integer *, complex *, 
	    integer *, real *), slamch_(char *);
    extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex 
	    *, integer *, complex *, integer *);
    static real abnorm, dum[1], ulp;


/*  -- LAPACK test routine (version 3.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       June 30, 1999   


    Purpose   
    =======   

    CGET54 checks a generalized decomposition of the form   

             A = U*S*V'  and B = U*T* V'   

    where ' means conjugate transpose and U and V are unitary.   

    Specifically,   

      RESULT = ||( A - U*S*V', B - U*T*V' )|| / (||( A, B )||*n*ulp )   

    Arguments   
    =========   

    N       (input) INTEGER   
            The size of the matrix.  If it is zero, SGET54 does nothing.   
            It must be at least zero.   

    A       (input) COMPLEX array, dimension (LDA, N)   
            The original (unfactored) matrix A.   

    LDA     (input) INTEGER   
            The leading dimension of A.  It must be at least 1   
            and at least N.   

    B       (input) COMPLEX array, dimension (LDB, N)   
            The original (unfactored) matrix B.   

    LDB     (input) INTEGER   
            The leading dimension of B.  It must be at least 1   
            and at least N.   

    S       (input) COMPLEX array, dimension (LDS, N)   
            The factored matrix S.   

    LDS     (input) INTEGER   
            The leading dimension of S.  It must be at least 1   
            and at least N.   

    T       (input) COMPLEX array, dimension (LDT, N)   
            The factored matrix T.   

    LDT     (input) INTEGER   
            The leading dimension of T.  It must be at least 1   
            and at least N.   

    U       (input) COMPLEX array, dimension (LDU, N)   
            The orthogonal matrix on the left-hand side in the   
            decomposition.   

    LDU     (input) INTEGER   
            The leading dimension of U.  LDU must be at least N and   
            at least 1.   

    V       (input) COMPLEX array, dimension (LDV, N)   
            The orthogonal matrix on the left-hand side in the   
            decomposition.   

    LDV     (input) INTEGER   
            The leading dimension of V.  LDV must be at least N and   
            at least 1.   

    WORK    (workspace) COMPLEX array, dimension (3*N**2)   

    RESULT  (output) REAL   
            The value RESULT, It is currently limited to 1/ulp, to   
            avoid overflow. Errors are flagged by RESULT=10/ulp.   

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


       Parameter adjustments */
    a_dim1 = *lda;
    a_offset = 1 + a_dim1 * 1;
    a -= a_offset;
    b_dim1 = *ldb;
    b_offset = 1 + b_dim1 * 1;
    b -= b_offset;
    s_dim1 = *lds;
    s_offset = 1 + s_dim1 * 1;
    s -= s_offset;
    t_dim1 = *ldt;
    t_offset = 1 + t_dim1 * 1;
    t -= t_offset;
    u_dim1 = *ldu;
    u_offset = 1 + u_dim1 * 1;
    u -= u_offset;
    v_dim1 = *ldv;
    v_offset = 1 + v_dim1 * 1;
    v -= v_offset;
    --work;

    /* Function Body */
    *result = 0.f;
    if (*n <= 0) {
	return 0;
    }

/*     Constants */

    unfl = slamch_("Safe minimum");
    ulp = slamch_("Epsilon") * slamch_("Base");

/*     compute the norm of (A,B) */

    clacpy_("Full", n, n, &a[a_offset], lda, &work[1], n);
    clacpy_("Full", n, n, &b[b_offset], ldb, &work[*n * *n + 1], n)
	    ;
/* Computing MAX */
    i__1 = *n << 1;
    r__1 = clange_("1", n, &i__1, &work[1], n, dum);
    abnorm = dmax(r__1,unfl);

/*     Compute W1 = A - U*S*V', and put in the array WORK(1:N*N) */

    clacpy_(" ", n, n, &a[a_offset], lda, &work[1], n);
    cgemm_("N", "N", n, n, n, &c_b2, &u[u_offset], ldu, &s[s_offset], lds, &
	    c_b1, &work[*n * *n + 1], n);

    q__1.r = -1.f, q__1.i = 0.f;
    cgemm_("N", "C", n, n, n, &q__1, &work[*n * *n + 1], n, &v[v_offset], ldv,
	     &c_b2, &work[1], n);

/*     Compute W2 = B - U*T*V', and put in the workarray W(N*N+1:2*N*N) */

    clacpy_(" ", n, n, &b[b_offset], ldb, &work[*n * *n + 1], n);
    cgemm_("N", "N", n, n, n, &c_b2, &u[u_offset], ldu, &t[t_offset], ldt, &
	    c_b1, &work[(*n << 1) * *n + 1], n);

    q__1.r = -1.f, q__1.i = 0.f;
    cgemm_("N", "C", n, n, n, &q__1, &work[(*n << 1) * *n + 1], n, &v[
	    v_offset], ldv, &c_b2, &work[*n * *n + 1], n);

/*     Compute norm(W)/ ( ulp*norm((A,B)) ) */

    i__1 = *n << 1;
    wnorm = clange_("1", n, &i__1, &work[1], n, dum);

    if (abnorm > wnorm) {
	*result = wnorm / abnorm / ((*n << 1) * ulp);
    } else {
	if (abnorm < 1.f) {
/* Computing MIN */
	    r__1 = wnorm, r__2 = (*n << 1) * abnorm;
	    *result = dmin(r__1,r__2) / abnorm / ((*n << 1) * ulp);
	} else {
/* Computing MIN */
	    r__1 = wnorm / abnorm, r__2 = (real) (*n << 1);
	    *result = dmin(r__1,r__2) / ((*n << 1) * ulp);
	}
    }

    return 0;

/*     End of CGET54 */

} /* cget54_ */

