chpt21.c
Go to the documentation of this file.
00001 /* chpt21.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__1 = 1;
00021 
00022 /* Subroutine */ int chpt21_(integer *itype, char *uplo, integer *n, integer *
00023         kband, complex *ap, real *d__, real *e, complex *u, integer *ldu, 
00024         complex *vp, complex *tau, complex *work, real *rwork, real *result)
00025 {
00026     /* System generated locals */
00027     integer u_dim1, u_offset, i__1, i__2, i__3, i__4, i__5, i__6;
00028     real r__1, r__2;
00029     complex q__1, q__2, q__3;
00030 
00031     /* Local variables */
00032     integer j, jp, jr, jp1, lap;
00033     real ulp;
00034     extern /* Subroutine */ int chpr_(char *, integer *, real *, complex *, 
00035             integer *, complex *);
00036     real unfl;
00037     complex temp;
00038     extern /* Subroutine */ int chpr2_(char *, integer *, complex *, complex *
00039 , integer *, complex *, integer *, complex *), cgemm_(
00040             char *, char *, integer *, integer *, integer *, complex *, 
00041             complex *, integer *, complex *, integer *, complex *, complex *, 
00042             integer *);
00043     extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer 
00044             *, complex *, integer *);
00045     extern logical lsame_(char *, char *);
00046     integer iinfo;
00047     real anorm;
00048     extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, 
00049             complex *, integer *), chpmv_(char *, integer *, complex *, 
00050             complex *, complex *, integer *, complex *, complex *, integer *);
00051     char cuplo[1];
00052     complex vsave;
00053     extern /* Subroutine */ int caxpy_(integer *, complex *, complex *, 
00054             integer *, complex *, integer *);
00055     logical lower;
00056     real wnorm;
00057     extern doublereal clange_(char *, integer *, integer *, complex *, 
00058             integer *, real *), clanhp_(char *, char *, integer *, 
00059             complex *, real *), slamch_(char *);
00060     extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex 
00061             *, integer *, complex *, integer *), claset_(char *, 
00062             integer *, integer *, complex *, complex *, complex *, integer *), cupmtr_(char *, char *, char *, integer *, integer *, 
00063             complex *, complex *, complex *, integer *, complex *, integer *);
00064 
00065 
00066 /*  -- LAPACK test routine (version 3.1) -- */
00067 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00068 /*     November 2006 */
00069 
00070 /*     .. Scalar Arguments .. */
00071 /*     .. */
00072 /*     .. Array Arguments .. */
00073 /*     .. */
00074 
00075 /*  Purpose */
00076 /*  ======= */
00077 
00078 /*  CHPT21  generally checks a decomposition of the form */
00079 
00080 /*          A = U S U* */
00081 
00082 /*  where * means conjugate transpose, A is hermitian, U is */
00083 /*  unitary, and S is diagonal (if KBAND=0) or (real) symmetric */
00084 /*  tridiagonal (if KBAND=1).  If ITYPE=1, then U is represented as */
00085 /*  a dense matrix, otherwise the U is expressed as a product of */
00086 /*  Householder transformations, whose vectors are stored in the */
00087 /*  array "V" and whose scaling constants are in "TAU"; we shall */
00088 /*  use the letter "V" to refer to the product of Householder */
00089 /*  transformations (which should be equal to U). */
00090 
00091 /*  Specifically, if ITYPE=1, then: */
00092 
00093 /*          RESULT(1) = | A - U S U* | / ( |A| n ulp ) *and* */
00094 /*          RESULT(2) = | I - UU* | / ( n ulp ) */
00095 
00096 /*  If ITYPE=2, then: */
00097 
00098 /*          RESULT(1) = | A - V S V* | / ( |A| n ulp ) */
00099 
00100 /*  If ITYPE=3, then: */
00101 
00102 /*          RESULT(1) = | I - UV* | / ( n ulp ) */
00103 
00104 /*  Packed storage means that, for example, if UPLO='U', then the columns */
00105 /*  of the upper triangle of A are stored one after another, so that */
00106 /*  A(1,j+1) immediately follows A(j,j) in the array AP.  Similarly, if */
00107 /*  UPLO='L', then the columns of the lower triangle of A are stored one */
00108 /*  after another in AP, so that A(j+1,j+1) immediately follows A(n,j) */
00109 /*  in the array AP.  This means that A(i,j) is stored in: */
00110 
00111 /*     AP( i + j*(j-1)/2 )                 if UPLO='U' */
00112 
00113 /*     AP( i + (2*n-j)*(j-1)/2 )           if UPLO='L' */
00114 
00115 /*  The array VP bears the same relation to the matrix V that A does to */
00116 /*  AP. */
00117 
00118 /*  For ITYPE > 1, the transformation U is expressed as a product */
00119 /*  of Householder transformations: */
00120 
00121 /*     If UPLO='U', then  V = H(n-1)...H(1),  where */
00122 
00123 /*         H(j) = I  -  tau(j) v(j) v(j)* */
00124 
00125 /*     and the first j-1 elements of v(j) are stored in V(1:j-1,j+1), */
00126 /*     (i.e., VP( j*(j+1)/2 + 1 : j*(j+1)/2 + j-1 ) ), */
00127 /*     the j-th element is 1, and the last n-j elements are 0. */
00128 
00129 /*     If UPLO='L', then  V = H(1)...H(n-1),  where */
00130 
00131 /*         H(j) = I  -  tau(j) v(j) v(j)* */
00132 
00133 /*     and the first j elements of v(j) are 0, the (j+1)-st is 1, and the */
00134 /*     (j+2)-nd through n-th elements are stored in V(j+2:n,j) (i.e., */
00135 /*     in VP( (2*n-j)*(j-1)/2 + j+2 : (2*n-j)*(j-1)/2 + n ) .) */
00136 
00137 /*  Arguments */
00138 /*  ========= */
00139 
00140 /*  ITYPE   (input) INTEGER */
00141 /*          Specifies the type of tests to be performed. */
00142 /*          1: U expressed as a dense unitary matrix: */
00143 /*             RESULT(1) = | A - U S U* | / ( |A| n ulp )   *and* */
00144 /*             RESULT(2) = | I - UU* | / ( n ulp ) */
00145 
00146 /*          2: U expressed as a product V of Housholder transformations: */
00147 /*             RESULT(1) = | A - V S V* | / ( |A| n ulp ) */
00148 
00149 /*          3: U expressed both as a dense unitary matrix and */
00150 /*             as a product of Housholder transformations: */
00151 /*             RESULT(1) = | I - UV* | / ( n ulp ) */
00152 
00153 /*  UPLO    (input) CHARACTER */
00154 /*          If UPLO='U', the upper triangle of A and V will be used and */
00155 /*          the (strictly) lower triangle will not be referenced. */
00156 /*          If UPLO='L', the lower triangle of A and V will be used and */
00157 /*          the (strictly) upper triangle will not be referenced. */
00158 
00159 /*  N       (input) INTEGER */
00160 /*          The size of the matrix.  If it is zero, CHPT21 does nothing. */
00161 /*          It must be at least zero. */
00162 
00163 /*  KBAND   (input) INTEGER */
00164 /*          The bandwidth of the matrix.  It may only be zero or one. */
00165 /*          If zero, then S is diagonal, and E is not referenced.  If */
00166 /*          one, then S is symmetric tri-diagonal. */
00167 
00168 /*  AP      (input) COMPLEX array, dimension (N*(N+1)/2) */
00169 /*          The original (unfactored) matrix.  It is assumed to be */
00170 /*          hermitian, and contains the columns of just the upper */
00171 /*          triangle (UPLO='U') or only the lower triangle (UPLO='L'), */
00172 /*          packed one after another. */
00173 
00174 /*  D       (input) REAL array, dimension (N) */
00175 /*          The diagonal of the (symmetric tri-) diagonal matrix. */
00176 
00177 /*  E       (input) REAL array, dimension (N) */
00178 /*          The off-diagonal of the (symmetric tri-) diagonal matrix. */
00179 /*          E(1) is the (1,2) and (2,1) element, E(2) is the (2,3) and */
00180 /*          (3,2) element, etc. */
00181 /*          Not referenced if KBAND=0. */
00182 
00183 /*  U       (input) COMPLEX array, dimension (LDU, N) */
00184 /*          If ITYPE=1 or 3, this contains the unitary matrix in */
00185 /*          the decomposition, expressed as a dense matrix.  If ITYPE=2, */
00186 /*          then it is not referenced. */
00187 
00188 /*  LDU     (input) INTEGER */
00189 /*          The leading dimension of U.  LDU must be at least N and */
00190 /*          at least 1. */
00191 
00192 /*  VP      (input) REAL array, dimension (N*(N+1)/2) */
00193 /*          If ITYPE=2 or 3, the columns of this array contain the */
00194 /*          Householder vectors used to describe the unitary matrix */
00195 /*          in the decomposition, as described in purpose. */
00196 /*          *NOTE* If ITYPE=2 or 3, V is modified and restored.  The */
00197 /*          subdiagonal (if UPLO='L') or the superdiagonal (if UPLO='U') */
00198 /*          is set to one, and later reset to its original value, during */
00199 /*          the course of the calculation. */
00200 /*          If ITYPE=1, then it is neither referenced nor modified. */
00201 
00202 /*  TAU     (input) COMPLEX array, dimension (N) */
00203 /*          If ITYPE >= 2, then TAU(j) is the scalar factor of */
00204 /*          v(j) v(j)* in the Householder transformation H(j) of */
00205 /*          the product  U = H(1)...H(n-2) */
00206 /*          If ITYPE < 2, then TAU is not referenced. */
00207 
00208 /*  WORK    (workspace) COMPLEX array, dimension (N**2) */
00209 /*          Workspace. */
00210 
00211 /*  RWORK   (workspace) REAL array, dimension (N) */
00212 /*          Workspace. */
00213 
00214 /*  RESULT  (output) REAL array, dimension (2) */
00215 /*          The values computed by the two tests described above.  The */
00216 /*          values are currently limited to 1/ulp, to avoid overflow. */
00217 /*          RESULT(1) is always modified.  RESULT(2) is modified only */
00218 /*          if ITYPE=1. */
00219 
00220 /*  ===================================================================== */
00221 
00222 /*     .. Parameters .. */
00223 /*     .. */
00224 /*     .. Local Scalars .. */
00225 /*     .. */
00226 /*     .. External Functions .. */
00227 /*     .. */
00228 /*     .. External Subroutines .. */
00229 /*     .. */
00230 /*     .. Intrinsic Functions .. */
00231 /*     .. */
00232 /*     .. Executable Statements .. */
00233 
00234 /*     Constants */
00235 
00236     /* Parameter adjustments */
00237     --ap;
00238     --d__;
00239     --e;
00240     u_dim1 = *ldu;
00241     u_offset = 1 + u_dim1;
00242     u -= u_offset;
00243     --vp;
00244     --tau;
00245     --work;
00246     --rwork;
00247     --result;
00248 
00249     /* Function Body */
00250     result[1] = 0.f;
00251     if (*itype == 1) {
00252         result[2] = 0.f;
00253     }
00254     if (*n <= 0) {
00255         return 0;
00256     }
00257 
00258     lap = *n * (*n + 1) / 2;
00259 
00260     if (lsame_(uplo, "U")) {
00261         lower = FALSE_;
00262         *(unsigned char *)cuplo = 'U';
00263     } else {
00264         lower = TRUE_;
00265         *(unsigned char *)cuplo = 'L';
00266     }
00267 
00268     unfl = slamch_("Safe minimum");
00269     ulp = slamch_("Epsilon") * slamch_("Base");
00270 
00271 /*     Some Error Checks */
00272 
00273     if (*itype < 1 || *itype > 3) {
00274         result[1] = 10.f / ulp;
00275         return 0;
00276     }
00277 
00278 /*     Do Test 1 */
00279 
00280 /*     Norm of A: */
00281 
00282     if (*itype == 3) {
00283         anorm = 1.f;
00284     } else {
00285 /* Computing MAX */
00286         r__1 = clanhp_("1", cuplo, n, &ap[1], &rwork[1])
00287                 ;
00288         anorm = dmax(r__1,unfl);
00289     }
00290 
00291 /*     Compute error matrix: */
00292 
00293     if (*itype == 1) {
00294 
00295 /*        ITYPE=1: error = A - U S U* */
00296 
00297         claset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00298         ccopy_(&lap, &ap[1], &c__1, &work[1], &c__1);
00299 
00300         i__1 = *n;
00301         for (j = 1; j <= i__1; ++j) {
00302             r__1 = -d__[j];
00303             chpr_(cuplo, n, &r__1, &u[j * u_dim1 + 1], &c__1, &work[1]);
00304 /* L10: */
00305         }
00306 
00307         if (*n > 1 && *kband == 1) {
00308             i__1 = *n - 1;
00309             for (j = 1; j <= i__1; ++j) {
00310                 i__2 = j;
00311                 q__2.r = e[i__2], q__2.i = 0.f;
00312                 q__1.r = -q__2.r, q__1.i = -q__2.i;
00313                 chpr2_(cuplo, n, &q__1, &u[j * u_dim1 + 1], &c__1, &u[(j - 1) 
00314                         * u_dim1 + 1], &c__1, &work[1]);
00315 /* L20: */
00316             }
00317         }
00318         wnorm = clanhp_("1", cuplo, n, &work[1], &rwork[1]);
00319 
00320     } else if (*itype == 2) {
00321 
00322 /*        ITYPE=2: error = V S V* - A */
00323 
00324         claset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00325 
00326         if (lower) {
00327             i__1 = lap;
00328             i__2 = *n;
00329             work[i__1].r = d__[i__2], work[i__1].i = 0.f;
00330             for (j = *n - 1; j >= 1; --j) {
00331                 jp = ((*n << 1) - j) * (j - 1) / 2;
00332                 jp1 = jp + *n - j;
00333                 if (*kband == 1) {
00334                     i__1 = jp + j + 1;
00335                     i__2 = j;
00336                     q__2.r = 1.f - tau[i__2].r, q__2.i = 0.f - tau[i__2].i;
00337                     i__3 = j;
00338                     q__1.r = e[i__3] * q__2.r, q__1.i = e[i__3] * q__2.i;
00339                     work[i__1].r = q__1.r, work[i__1].i = q__1.i;
00340                     i__1 = *n;
00341                     for (jr = j + 2; jr <= i__1; ++jr) {
00342                         i__2 = jp + jr;
00343                         i__3 = j;
00344                         q__3.r = -tau[i__3].r, q__3.i = -tau[i__3].i;
00345                         i__4 = j;
00346                         q__2.r = e[i__4] * q__3.r, q__2.i = e[i__4] * q__3.i;
00347                         i__5 = jp + jr;
00348                         q__1.r = q__2.r * vp[i__5].r - q__2.i * vp[i__5].i, 
00349                                 q__1.i = q__2.r * vp[i__5].i + q__2.i * vp[
00350                                 i__5].r;
00351                         work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00352 /* L30: */
00353                     }
00354                 }
00355 
00356                 i__1 = j;
00357                 if (tau[i__1].r != 0.f || tau[i__1].i != 0.f) {
00358                     i__1 = jp + j + 1;
00359                     vsave.r = vp[i__1].r, vsave.i = vp[i__1].i;
00360                     i__1 = jp + j + 1;
00361                     vp[i__1].r = 1.f, vp[i__1].i = 0.f;
00362                     i__1 = *n - j;
00363                     chpmv_("L", &i__1, &c_b2, &work[jp1 + j + 1], &vp[jp + j 
00364                             + 1], &c__1, &c_b1, &work[lap + 1], &c__1);
00365                     i__1 = j;
00366                     q__2.r = tau[i__1].r * -.5f, q__2.i = tau[i__1].i * -.5f;
00367                     i__2 = *n - j;
00368                     cdotc_(&q__3, &i__2, &work[lap + 1], &c__1, &vp[jp + j + 
00369                             1], &c__1);
00370                     q__1.r = q__2.r * q__3.r - q__2.i * q__3.i, q__1.i = 
00371                             q__2.r * q__3.i + q__2.i * q__3.r;
00372                     temp.r = q__1.r, temp.i = q__1.i;
00373                     i__1 = *n - j;
00374                     caxpy_(&i__1, &temp, &vp[jp + j + 1], &c__1, &work[lap + 
00375                             1], &c__1);
00376                     i__1 = *n - j;
00377                     i__2 = j;
00378                     q__1.r = -tau[i__2].r, q__1.i = -tau[i__2].i;
00379                     chpr2_("L", &i__1, &q__1, &vp[jp + j + 1], &c__1, &work[
00380                             lap + 1], &c__1, &work[jp1 + j + 1]);
00381 
00382                     i__1 = jp + j + 1;
00383                     vp[i__1].r = vsave.r, vp[i__1].i = vsave.i;
00384                 }
00385                 i__1 = jp + j;
00386                 i__2 = j;
00387                 work[i__1].r = d__[i__2], work[i__1].i = 0.f;
00388 /* L40: */
00389             }
00390         } else {
00391             work[1].r = d__[1], work[1].i = 0.f;
00392             i__1 = *n - 1;
00393             for (j = 1; j <= i__1; ++j) {
00394                 jp = j * (j - 1) / 2;
00395                 jp1 = jp + j;
00396                 if (*kband == 1) {
00397                     i__2 = jp1 + j;
00398                     i__3 = j;
00399                     q__2.r = 1.f - tau[i__3].r, q__2.i = 0.f - tau[i__3].i;
00400                     i__4 = j;
00401                     q__1.r = e[i__4] * q__2.r, q__1.i = e[i__4] * q__2.i;
00402                     work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00403                     i__2 = j - 1;
00404                     for (jr = 1; jr <= i__2; ++jr) {
00405                         i__3 = jp1 + jr;
00406                         i__4 = j;
00407                         q__3.r = -tau[i__4].r, q__3.i = -tau[i__4].i;
00408                         i__5 = j;
00409                         q__2.r = e[i__5] * q__3.r, q__2.i = e[i__5] * q__3.i;
00410                         i__6 = jp1 + jr;
00411                         q__1.r = q__2.r * vp[i__6].r - q__2.i * vp[i__6].i, 
00412                                 q__1.i = q__2.r * vp[i__6].i + q__2.i * vp[
00413                                 i__6].r;
00414                         work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00415 /* L50: */
00416                     }
00417                 }
00418 
00419                 i__2 = j;
00420                 if (tau[i__2].r != 0.f || tau[i__2].i != 0.f) {
00421                     i__2 = jp1 + j;
00422                     vsave.r = vp[i__2].r, vsave.i = vp[i__2].i;
00423                     i__2 = jp1 + j;
00424                     vp[i__2].r = 1.f, vp[i__2].i = 0.f;
00425                     chpmv_("U", &j, &c_b2, &work[1], &vp[jp1 + 1], &c__1, &
00426                             c_b1, &work[lap + 1], &c__1);
00427                     i__2 = j;
00428                     q__2.r = tau[i__2].r * -.5f, q__2.i = tau[i__2].i * -.5f;
00429                     cdotc_(&q__3, &j, &work[lap + 1], &c__1, &vp[jp1 + 1], &
00430                             c__1);
00431                     q__1.r = q__2.r * q__3.r - q__2.i * q__3.i, q__1.i = 
00432                             q__2.r * q__3.i + q__2.i * q__3.r;
00433                     temp.r = q__1.r, temp.i = q__1.i;
00434                     caxpy_(&j, &temp, &vp[jp1 + 1], &c__1, &work[lap + 1], &
00435                             c__1);
00436                     i__2 = j;
00437                     q__1.r = -tau[i__2].r, q__1.i = -tau[i__2].i;
00438                     chpr2_("U", &j, &q__1, &vp[jp1 + 1], &c__1, &work[lap + 1]
00439 , &c__1, &work[1]);
00440                     i__2 = jp1 + j;
00441                     vp[i__2].r = vsave.r, vp[i__2].i = vsave.i;
00442                 }
00443                 i__2 = jp1 + j + 1;
00444                 i__3 = j + 1;
00445                 work[i__2].r = d__[i__3], work[i__2].i = 0.f;
00446 /* L60: */
00447             }
00448         }
00449 
00450         i__1 = lap;
00451         for (j = 1; j <= i__1; ++j) {
00452             i__2 = j;
00453             i__3 = j;
00454             i__4 = j;
00455             q__1.r = work[i__3].r - ap[i__4].r, q__1.i = work[i__3].i - ap[
00456                     i__4].i;
00457             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00458 /* L70: */
00459         }
00460         wnorm = clanhp_("1", cuplo, n, &work[1], &rwork[1]);
00461 
00462     } else if (*itype == 3) {
00463 
00464 /*        ITYPE=3: error = U V* - I */
00465 
00466         if (*n < 2) {
00467             return 0;
00468         }
00469         clacpy_(" ", n, n, &u[u_offset], ldu, &work[1], n);
00470 /* Computing 2nd power */
00471         i__1 = *n;
00472         cupmtr_("R", cuplo, "C", n, n, &vp[1], &tau[1], &work[1], n, &work[
00473                 i__1 * i__1 + 1], &iinfo);
00474         if (iinfo != 0) {
00475             result[1] = 10.f / ulp;
00476             return 0;
00477         }
00478 
00479         i__1 = *n;
00480         for (j = 1; j <= i__1; ++j) {
00481             i__2 = (*n + 1) * (j - 1) + 1;
00482             i__3 = (*n + 1) * (j - 1) + 1;
00483             q__1.r = work[i__3].r - 1.f, q__1.i = work[i__3].i - 0.f;
00484             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00485 /* L80: */
00486         }
00487 
00488         wnorm = clange_("1", n, n, &work[1], n, &rwork[1]);
00489     }
00490 
00491     if (anorm > wnorm) {
00492         result[1] = wnorm / anorm / (*n * ulp);
00493     } else {
00494         if (anorm < 1.f) {
00495 /* Computing MIN */
00496             r__1 = wnorm, r__2 = *n * anorm;
00497             result[1] = dmin(r__1,r__2) / anorm / (*n * ulp);
00498         } else {
00499 /* Computing MIN */
00500             r__1 = wnorm / anorm, r__2 = (real) (*n);
00501             result[1] = dmin(r__1,r__2) / (*n * ulp);
00502         }
00503     }
00504 
00505 /*     Do Test 2 */
00506 
00507 /*     Compute  UU* - I */
00508 
00509     if (*itype == 1) {
00510         cgemm_("N", "C", n, n, n, &c_b2, &u[u_offset], ldu, &u[u_offset], ldu, 
00511                  &c_b1, &work[1], n);
00512 
00513         i__1 = *n;
00514         for (j = 1; j <= i__1; ++j) {
00515             i__2 = (*n + 1) * (j - 1) + 1;
00516             i__3 = (*n + 1) * (j - 1) + 1;
00517             q__1.r = work[i__3].r - 1.f, q__1.i = work[i__3].i - 0.f;
00518             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00519 /* L90: */
00520         }
00521 
00522 /* Computing MIN */
00523         r__1 = clange_("1", n, n, &work[1], n, &rwork[1]), r__2 = (
00524                 real) (*n);
00525         result[2] = dmin(r__1,r__2) / (*n * ulp);
00526     }
00527 
00528     return 0;
00529 
00530 /*     End of CHPT21 */
00531 
00532 } /* chpt21_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:29