Add a BLAS3-based triangular Sylvester equation solver (Reference-LAPACK PR 651)tags/v0.3.22^2
| @@ -123,7 +123,8 @@ set(SLASRC | |||
| ssyevd_2stage.f ssyev_2stage.f ssyevx_2stage.f ssyevr_2stage.f | |||
| ssbev_2stage.f ssbevx_2stage.f ssbevd_2stage.f ssygv_2stage.f | |||
| sgesvdq.f slaorhr_col_getrfnp.f | |||
| slaorhr_col_getrfnp2.f sorgtsqr.f sorgtsqr_row.f sorhr_col.f ) | |||
| slaorhr_col_getrfnp2.f sorgtsqr.f sorgtsqr_row.f sorhr_col.f | |||
| slarmm.f slatrs3.f strsyl3.f) | |||
| set(SXLASRC sgesvxx.f sgerfsx.f sla_gerfsx_extended.f sla_geamv.f | |||
| sla_gercond.f sla_gerpvgrw.f ssysvxx.f ssyrfsx.f | |||
| @@ -221,7 +222,8 @@ set(CLASRC | |||
| cheevd_2stage.f cheev_2stage.f cheevx_2stage.f cheevr_2stage.f | |||
| chbev_2stage.f chbevx_2stage.f chbevd_2stage.f chegv_2stage.f | |||
| cgesvdq.f claunhr_col_getrfnp.f claunhr_col_getrfnp2.f | |||
| cungtsqr.f cungtsqr_row.f cunhr_col.f ) | |||
| cungtsqr.f cungtsqr_row.f cunhr_col.f | |||
| clatrs3.f ctrsyl3.f ) | |||
| set(CXLASRC cgesvxx.f cgerfsx.f cla_gerfsx_extended.f cla_geamv.f | |||
| cla_gercond_c.f cla_gercond_x.f cla_gerpvgrw.f | |||
| @@ -313,7 +315,8 @@ set(DLASRC | |||
| dsyevd_2stage.f dsyev_2stage.f dsyevx_2stage.f dsyevr_2stage.f | |||
| dsbev_2stage.f dsbevx_2stage.f dsbevd_2stage.f dsygv_2stage.f | |||
| dcombssq.f dgesvdq.f dlaorhr_col_getrfnp.f | |||
| dlaorhr_col_getrfnp2.f dorgtsqr.f dorgtsqr_row.f dorhr_col.f ) | |||
| dlaorhr_col_getrfnp2.f dorgtsqr.f dorgtsqr_row.f dorhr_col.f | |||
| dlarmm.f dlatrs3.f dtrsyl3.f) | |||
| set(DXLASRC dgesvxx.f dgerfsx.f dla_gerfsx_extended.f dla_geamv.f | |||
| dla_gercond.f dla_gerpvgrw.f dsysvxx.f dsyrfsx.f | |||
| @@ -415,7 +418,8 @@ set(ZLASRC | |||
| zheevd_2stage.f zheev_2stage.f zheevx_2stage.f zheevr_2stage.f | |||
| zhbev_2stage.f zhbevx_2stage.f zhbevd_2stage.f zhegv_2stage.f | |||
| zgesvdq.f zlaunhr_col_getrfnp.f zlaunhr_col_getrfnp2.f | |||
| zungtsqr.f zungtsqr_row.f zunhr_col.f) | |||
| zungtsqr.f zungtsqr_row.f zunhr_col.f | |||
| zlatrs3.f ztrsyl3.f) | |||
| set(ZXLASRC zgesvxx.f zgerfsx.f zla_gerfsx_extended.f zla_geamv.f | |||
| zla_gercond_c.f zla_gercond_x.f zla_gerpvgrw.f zsysvxx.f zsyrfsx.f | |||
| @@ -617,7 +621,8 @@ set(SLASRC | |||
| ssyevd_2stage.c ssyev_2stage.c ssyevx_2stage.c ssyevr_2stage.c | |||
| ssbev_2stage.c ssbevx_2stage.c ssbevd_2stage.c ssygv_2stage.c | |||
| sgesvdq.c slaorhr_col_getrfnp.c | |||
| slaorhr_col_getrfnp2.c sorgtsqr.c sorgtsqr_row.c sorhr_col.c ) | |||
| slaorhr_col_getrfnp2.c sorgtsqr.c sorgtsqr_row.c sorhr_col.c | |||
| slarmm.c slatrs3.c strsyl3.c) | |||
| set(SXLASRC sgesvxx.c sgerfsx.c sla_gerfsx_extended.c sla_geamv.c | |||
| sla_gercond.c sla_gerpvgrw.c ssysvxx.c ssyrfsx.c | |||
| @@ -714,7 +719,8 @@ set(CLASRC | |||
| cheevd_2stage.c cheev_2stage.c cheevx_2stage.c cheevr_2stage.c | |||
| chbev_2stage.c chbevx_2stage.c chbevd_2stage.c chegv_2stage.c | |||
| cgesvdq.c claunhr_col_getrfnp.c claunhr_col_getrfnp2.c | |||
| cungtsqr.c cungtsqr_row.c cunhr_col.c ) | |||
| cungtsqr.c cungtsqr_row.c cunhr_col.c | |||
| clatrs3.c ctrsyl3.c) | |||
| set(CXLASRC cgesvxx.c cgerfsx.c cla_gerfsx_extended.c cla_geamv.c | |||
| cla_gercond_c.c cla_gercond_x.c cla_gerpvgrw.c | |||
| @@ -805,7 +811,8 @@ set(DLASRC | |||
| dsyevd_2stage.c dsyev_2stage.c dsyevx_2stage.c dsyevr_2stage.c | |||
| dsbev_2stage.c dsbevx_2stage.c dsbevd_2stage.c dsygv_2stage.c | |||
| dcombssq.c dgesvdq.c dlaorhr_col_getrfnp.c | |||
| dlaorhr_col_getrfnp2.c dorgtsqr.c dorgtsqr_row.c dorhr_col.c ) | |||
| dlaorhr_col_getrfnp2.c dorgtsqr.c dorgtsqr_row.c dorhr_col.c | |||
| dlarmm.c dlatrs3.c dtrsyl3.c) | |||
| set(DXLASRC dgesvxx.c dgerfsx.c dla_gerfsx_extended.c dla_geamv.c | |||
| dla_gercond.c dla_gerpvgrw.c dsysvxx.c dsyrfsx.c | |||
| @@ -906,7 +913,7 @@ set(ZLASRC | |||
| zheevd_2stage.c zheev_2stage.c zheevx_2stage.c zheevr_2stage.c | |||
| zhbev_2stage.c zhbevx_2stage.c zhbevd_2stage.c zhegv_2stage.c | |||
| zgesvdq.c zlaunhr_col_getrfnp.c zlaunhr_col_getrfnp2.c | |||
| zungtsqr.c zungtsqr_row.c zunhr_col.c) | |||
| zungtsqr.c zungtsqr_row.c zunhr_col.c zlatrs3.c ztrsyl3.c) | |||
| set(ZXLASRC zgesvxx.c zgerfsx.c zla_gerfsx_extended.c zla_geamv.c | |||
| zla_gercond_c.c zla_gercond_x.c zla_gerpvgrw.c zsysvxx.c zsyrfsx.c | |||
| @@ -12,6 +12,7 @@ | |||
| #include <stdlib.h> | |||
| #include <stdarg.h> | |||
| #include <inttypes.h> | |||
| /* It seems all current Fortran compilers put strlen at end. | |||
| * Some historical compilers put strlen after the str argument | |||
| @@ -80,11 +81,26 @@ extern "C" { | |||
| /*----------------------------------------------------------------------------*/ | |||
| #ifndef lapack_int | |||
| #define lapack_int int | |||
| #if defined(LAPACK_ILP64) | |||
| #define lapack_int int64_t | |||
| #else | |||
| #define lapack_int int32_t | |||
| #endif | |||
| #endif | |||
| /* | |||
| * Integer format string | |||
| */ | |||
| #ifndef LAPACK_IFMT | |||
| #if defined(LAPACK_ILP64) | |||
| #define LAPACK_IFMT PRId64 | |||
| #else | |||
| #define LAPACK_IFMT PRId32 | |||
| #endif | |||
| #endif | |||
| #ifndef lapack_logical | |||
| #define lapack_logical lapack_int | |||
| #define lapack_logical lapack_int | |||
| #endif | |||
| /* f2c, hence clapack and MacOS Accelerate, returns double instead of float | |||
| @@ -115,7 +131,7 @@ typedef lapack_logical (*LAPACK_Z_SELECT2) | |||
| ( const lapack_complex_double*, const lapack_complex_double* ); | |||
| #define LAPACK_lsame_base LAPACK_GLOBAL(lsame,LSAME) | |||
| lapack_logical LAPACK_lsame_base( const char* ca, const char* cb, | |||
| lapack_logical LAPACK_lsame_base( const char* ca, const char* cb, | |||
| lapack_int lca, lapack_int lcb | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| , size_t, size_t | |||
| @@ -21986,6 +22002,84 @@ void LAPACK_ztrsyl_base( | |||
| #define LAPACK_ztrsyl(...) LAPACK_ztrsyl_base(__VA_ARGS__) | |||
| #endif | |||
| #define LAPACK_ctrsyl3_base LAPACK_GLOBAL(ctrsyl3,CTRSYL3) | |||
| void LAPACK_ctrsyl3_base( | |||
| char const* trana, char const* tranb, | |||
| lapack_int const* isgn, lapack_int const* m, lapack_int const* n, | |||
| lapack_complex_float const* A, lapack_int const* lda, | |||
| lapack_complex_float const* B, lapack_int const* ldb, | |||
| lapack_complex_float* C, lapack_int const* ldc, float* scale, | |||
| float* swork, lapack_int const *ldswork, | |||
| lapack_int* info | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| , size_t, size_t | |||
| #endif | |||
| ); | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| #define LAPACK_ctrsyl3(...) LAPACK_ctrsyl3_base(__VA_ARGS__, 1, 1) | |||
| #else | |||
| #define LAPACK_ctrsyl3(...) LAPACK_ctrsyl3_base(__VA_ARGS__) | |||
| #endif | |||
| #define LAPACK_dtrsyl3_base LAPACK_GLOBAL(dtrsyl3,DTRSYL3) | |||
| void LAPACK_dtrsyl3_base( | |||
| char const* trana, char const* tranb, | |||
| lapack_int const* isgn, lapack_int const* m, lapack_int const* n, | |||
| double const* A, lapack_int const* lda, | |||
| double const* B, lapack_int const* ldb, | |||
| double* C, lapack_int const* ldc, double* scale, | |||
| lapack_int* iwork, lapack_int const* liwork, | |||
| double* swork, lapack_int const *ldswork, | |||
| lapack_int* info | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| , size_t, size_t | |||
| #endif | |||
| ); | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| #define LAPACK_dtrsyl3(...) LAPACK_dtrsyl3_base(__VA_ARGS__, 1, 1) | |||
| #else | |||
| #define LAPACK_dtrsyl3(...) LAPACK_dtrsyl3_base(__VA_ARGS__) | |||
| #endif | |||
| #define LAPACK_strsyl3_base LAPACK_GLOBAL(strsyl3,STRSYL3) | |||
| void LAPACK_strsyl3_base( | |||
| char const* trana, char const* tranb, | |||
| lapack_int const* isgn, lapack_int const* m, lapack_int const* n, | |||
| float const* A, lapack_int const* lda, | |||
| float const* B, lapack_int const* ldb, | |||
| float* C, lapack_int const* ldc, float* scale, | |||
| lapack_int* iwork, lapack_int const* liwork, | |||
| float* swork, lapack_int const *ldswork, | |||
| lapack_int* info | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| , size_t, size_t | |||
| #endif | |||
| ); | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| #define LAPACK_strsyl3(...) LAPACK_strsyl3_base(__VA_ARGS__, 1, 1) | |||
| #else | |||
| #define LAPACK_strsyl3(...) LAPACK_strsyl3_base(__VA_ARGS__) | |||
| #endif | |||
| #define LAPACK_ztrsyl3_base LAPACK_GLOBAL(ztrsyl3,ZTRSYL3) | |||
| void LAPACK_ztrsyl3_base( | |||
| char const* trana, char const* tranb, | |||
| lapack_int const* isgn, lapack_int const* m, lapack_int const* n, | |||
| lapack_complex_double const* A, lapack_int const* lda, | |||
| lapack_complex_double const* B, lapack_int const* ldb, | |||
| lapack_complex_double* C, lapack_int const* ldc, double* scale, | |||
| double* swork, lapack_int const *ldswork, | |||
| lapack_int* info | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| , size_t, size_t | |||
| #endif | |||
| ); | |||
| #ifdef LAPACK_FORTRAN_STRLEN_END | |||
| #define LAPACK_ztrsyl3(...) LAPACK_ztrsyl3_base(__VA_ARGS__, 1, 1) | |||
| #else | |||
| #define LAPACK_ztrsyl3(...) LAPACK_ztrsyl3_base(__VA_ARGS__) | |||
| #endif | |||
| #define LAPACK_ctrtri_base LAPACK_GLOBAL(ctrtri,CTRTRI) | |||
| void LAPACK_ctrtri_base( | |||
| char const* uplo, char const* diag, | |||
| @@ -2313,6 +2313,19 @@ lapack_int LAPACKE_zlagge( int matrix_layout, lapack_int m, lapack_int n, | |||
| float LAPACKE_slamch( char cmach ); | |||
| double LAPACKE_dlamch( char cmach ); | |||
| float LAPACKE_slangb( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, const float* ab, | |||
| lapack_int ldab ); | |||
| double LAPACKE_dlangb( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, const double* ab, | |||
| lapack_int ldab ); | |||
| float LAPACKE_clangb( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, | |||
| const lapack_complex_float* ab, lapack_int ldab ); | |||
| double LAPACKE_zlangb( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, | |||
| const lapack_complex_double* ab, lapack_int ldab ); | |||
| float LAPACKE_slange( int matrix_layout, char norm, lapack_int m, | |||
| lapack_int n, const float* a, lapack_int lda ); | |||
| double LAPACKE_dlange( int matrix_layout, char norm, lapack_int m, | |||
| @@ -4477,6 +4490,23 @@ lapack_int LAPACKE_ztrsyl( int matrix_layout, char trana, char tranb, | |||
| lapack_complex_double* c, lapack_int ldc, | |||
| double* scale ); | |||
| lapack_int LAPACKE_strsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const float* a, lapack_int lda, const float* b, | |||
| lapack_int ldb, float* c, lapack_int ldc, | |||
| float* scale ); | |||
| lapack_int LAPACKE_dtrsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const double* a, lapack_int lda, const double* b, | |||
| lapack_int ldb, double* c, lapack_int ldc, | |||
| double* scale ); | |||
| lapack_int LAPACKE_ztrsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_double* a, lapack_int lda, | |||
| const lapack_complex_double* b, lapack_int ldb, | |||
| lapack_complex_double* c, lapack_int ldc, | |||
| double* scale ); | |||
| lapack_int LAPACKE_strtri( int matrix_layout, char uplo, char diag, lapack_int n, | |||
| float* a, lapack_int lda ); | |||
| lapack_int LAPACKE_dtrtri( int matrix_layout, char uplo, char diag, lapack_int n, | |||
| @@ -7576,6 +7606,21 @@ double LAPACKE_dlapy3_work( double x, double y, double z ); | |||
| float LAPACKE_slamch_work( char cmach ); | |||
| double LAPACKE_dlamch_work( char cmach ); | |||
| float LAPACKE_slangb_work( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, const float* ab, | |||
| lapack_int ldab, float* work ); | |||
| double LAPACKE_dlangb_work( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, const double* ab, | |||
| lapack_int ldab, double* work ); | |||
| float LAPACKE_clangb_work( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, | |||
| const lapack_complex_float* ab, lapack_int ldab, | |||
| float* work ); | |||
| double LAPACKE_zlangb_work( int matrix_layout, char norm, lapack_int n, | |||
| lapack_int kl, lapack_int ku, | |||
| const lapack_complex_double* ab, lapack_int ldab, | |||
| double* work ); | |||
| float LAPACKE_slange_work( int matrix_layout, char norm, lapack_int m, | |||
| lapack_int n, const float* a, lapack_int lda, | |||
| float* work ); | |||
| @@ -10174,6 +10219,35 @@ lapack_int LAPACKE_ztrsyl_work( int matrix_layout, char trana, char tranb, | |||
| lapack_complex_double* c, lapack_int ldc, | |||
| double* scale ); | |||
| lapack_int LAPACKE_strsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const float* a, lapack_int lda, | |||
| const float* b, lapack_int ldb, | |||
| float* c, lapack_int ldc, float* scale, | |||
| lapack_int* iwork, lapack_int liwork, | |||
| float* swork, lapack_int ldswork ); | |||
| lapack_int LAPACKE_dtrsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const double* a, lapack_int lda, | |||
| const double* b, lapack_int ldb, | |||
| double* c, lapack_int ldc, double* scale, | |||
| lapack_int* iwork, lapack_int liwork, | |||
| double* swork, lapack_int ldswork ); | |||
| lapack_int LAPACKE_ctrsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_float* a, lapack_int lda, | |||
| const lapack_complex_float* b, lapack_int ldb, | |||
| lapack_complex_float* c, lapack_int ldc, | |||
| float* scale, float* swork, | |||
| lapack_int ldswork ); | |||
| lapack_int LAPACKE_ztrsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_double* a, lapack_int lda, | |||
| const lapack_complex_double* b, lapack_int ldb, | |||
| lapack_complex_double* c, lapack_int ldc, | |||
| double* scale, double* swork, | |||
| lapack_int ldswork ); | |||
| lapack_int LAPACKE_strtri_work( int matrix_layout, char uplo, char diag, | |||
| lapack_int n, float* a, lapack_int lda ); | |||
| lapack_int LAPACKE_dtrtri_work( int matrix_layout, char uplo, char diag, | |||
| @@ -48,7 +48,6 @@ lapack_int LAPACKE_cgesvdq( int matrix_layout, char joba, char jobp, | |||
| lapack_int lrwork = -1; | |||
| float* rwork = NULL; | |||
| float rwork_query; | |||
| lapack_int i; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_cgesvdq", -1 ); | |||
| return -1; | |||
| @@ -0,0 +1,56 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_ctrsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_float* a, lapack_int lda, | |||
| const lapack_complex_float* b, lapack_int ldb, | |||
| lapack_complex_float* c, lapack_int ldc, | |||
| float* scale ) | |||
| { | |||
| lapack_int info = 0; | |||
| float swork_query[2]; | |||
| float* swork = NULL; | |||
| lapack_int ldswork = -1; | |||
| lapack_int swork_size = -1; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3", -1 ); | |||
| return -1; | |||
| } | |||
| #ifndef LAPACK_DISABLE_NAN_CHECK | |||
| if( LAPACKE_get_nancheck() ) { | |||
| /* Optionally check input matrices for NaNs */ | |||
| if( LAPACKE_cge_nancheck( matrix_layout, m, m, a, lda ) ) { | |||
| return -7; | |||
| } | |||
| if( LAPACKE_cge_nancheck( matrix_layout, n, n, b, ldb ) ) { | |||
| return -9; | |||
| } | |||
| if( LAPACKE_cge_nancheck( matrix_layout, m, n, c, ldc ) ) { | |||
| return -11; | |||
| } | |||
| } | |||
| #endif | |||
| /* Query optimal working array sizes */ | |||
| info = LAPACKE_ctrsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, lda, | |||
| b, ldb, c, ldc, scale, swork_query, ldswork ); | |||
| if( info != 0 ) { | |||
| goto exit_level_0; | |||
| } | |||
| ldswork = swork_query[0]; | |||
| swork_size = ldswork * swork_query[1]; | |||
| swork = (float*)LAPACKE_malloc( sizeof(float) * swork_size); | |||
| if( swork == NULL ) { | |||
| info = LAPACK_WORK_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| /* Call middle-level interface */ | |||
| info = LAPACKE_ctrsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, | |||
| lda, b, ldb, c, ldc, scale, swork, ldswork ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( swork ); | |||
| exit_level_0: | |||
| if( info == LAPACK_WORK_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -0,0 +1,88 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_ctrsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_float* a, lapack_int lda, | |||
| const lapack_complex_float* b, lapack_int ldb, | |||
| lapack_complex_float* c, lapack_int ldc, | |||
| float* scale, float* swork, | |||
| lapack_int ldswork ) | |||
| { | |||
| lapack_int info = 0; | |||
| if( matrix_layout == LAPACK_COL_MAJOR ) { | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_ctrsyl3( &trana, &tranb, &isgn, &m, &n, a, &lda, b, &ldb, c, &ldc, | |||
| scale, swork, &ldswork, &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| } else if( matrix_layout == LAPACK_ROW_MAJOR ) { | |||
| lapack_int lda_t = MAX(1,m); | |||
| lapack_int ldb_t = MAX(1,n); | |||
| lapack_int ldc_t = MAX(1,m); | |||
| lapack_complex_float* a_t = NULL; | |||
| lapack_complex_float* b_t = NULL; | |||
| lapack_complex_float* c_t = NULL; | |||
| /* Check leading dimension(s) */ | |||
| if( lda < m ) { | |||
| info = -8; | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldb < n ) { | |||
| info = -10; | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldc < n ) { | |||
| info = -12; | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| /* Allocate memory for temporary array(s) */ | |||
| a_t = (lapack_complex_float*) | |||
| LAPACKE_malloc( sizeof(lapack_complex_float) * lda_t * MAX(1,m) ); | |||
| if( a_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| b_t = (lapack_complex_float*) | |||
| LAPACKE_malloc( sizeof(lapack_complex_float) * ldb_t * MAX(1,n) ); | |||
| if( b_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_1; | |||
| } | |||
| c_t = (lapack_complex_float*) | |||
| LAPACKE_malloc( sizeof(lapack_complex_float) * ldc_t * MAX(1,n) ); | |||
| if( c_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_2; | |||
| } | |||
| /* Transpose input matrices */ | |||
| LAPACKE_cge_trans( matrix_layout, m, m, a, lda, a_t, lda_t ); | |||
| LAPACKE_cge_trans( matrix_layout, n, n, b, ldb, b_t, ldb_t ); | |||
| LAPACKE_cge_trans( matrix_layout, m, n, c, ldc, c_t, ldc_t ); | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_ctrsyl3( &trana, &tranb, &isgn, &m, &n, a_t, &lda_t, b_t, &ldb_t, | |||
| c_t, &ldc_t, scale, swork, &ldswork, &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| /* Transpose output matrices */ | |||
| LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, n, c_t, ldc_t, c, ldc ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( c_t ); | |||
| exit_level_2: | |||
| LAPACKE_free( b_t ); | |||
| exit_level_1: | |||
| LAPACKE_free( a_t ); | |||
| exit_level_0: | |||
| if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3_work", info ); | |||
| } | |||
| } else { | |||
| info = -1; | |||
| LAPACKE_xerbla( "LAPACKE_ctrsyl3_work", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -48,7 +48,6 @@ lapack_int LAPACKE_dgesvdq( int matrix_layout, char joba, char jobp, | |||
| lapack_int lrwork = -1; | |||
| double* rwork = NULL; | |||
| double rwork_query; | |||
| lapack_int i; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_dgesvdq", -1 ); | |||
| return -1; | |||
| @@ -0,0 +1,68 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_dtrsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const double* a, lapack_int lda, const double* b, | |||
| lapack_int ldb, double* c, lapack_int ldc, | |||
| double* scale ) | |||
| { | |||
| lapack_int info = 0; | |||
| double swork_query[2]; | |||
| double* swork = NULL; | |||
| lapack_int ldswork = -1; | |||
| lapack_int swork_size = -1; | |||
| lapack_int iwork_query; | |||
| lapack_int* iwork = NULL; | |||
| lapack_int liwork = -1; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3", -1 ); | |||
| return -1; | |||
| } | |||
| #ifndef LAPACK_DISABLE_NAN_CHECK | |||
| if( LAPACKE_get_nancheck() ) { | |||
| /* Optionally check input matrices for NaNs */ | |||
| if( LAPACKE_dge_nancheck( matrix_layout, m, m, a, lda ) ) { | |||
| return -7; | |||
| } | |||
| if( LAPACKE_dge_nancheck( matrix_layout, n, n, b, ldb ) ) { | |||
| return -9; | |||
| } | |||
| if( LAPACKE_dge_nancheck( matrix_layout, m, n, c, ldc ) ) { | |||
| return -11; | |||
| } | |||
| } | |||
| #endif | |||
| /* Query optimal working array sizes */ | |||
| info = LAPACKE_dtrsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, lda, | |||
| b, ldb, c, ldc, scale, &iwork_query, liwork, | |||
| swork_query, ldswork ); | |||
| if( info != 0 ) { | |||
| goto exit_level_0; | |||
| } | |||
| ldswork = swork_query[0]; | |||
| swork_size = ldswork * swork_query[1]; | |||
| swork = (double*)LAPACKE_malloc( sizeof(double) * swork_size); | |||
| if( swork == NULL ) { | |||
| info = LAPACK_WORK_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| liwork = iwork_query; | |||
| iwork = (lapack_int*)LAPACKE_malloc( sizeof(lapack_int) * liwork ); | |||
| if ( iwork == NULL ) { | |||
| info = LAPACK_WORK_MEMORY_ERROR; | |||
| goto exit_level_1; | |||
| } | |||
| /* Call middle-level interface */ | |||
| info = LAPACKE_dtrsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, | |||
| lda, b, ldb, c, ldc, scale, iwork, liwork, | |||
| swork, ldswork ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( iwork ); | |||
| exit_level_1: | |||
| LAPACKE_free( swork ); | |||
| exit_level_0: | |||
| if( info == LAPACK_WORK_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -0,0 +1,86 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_dtrsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const double* a, lapack_int lda, | |||
| const double* b, lapack_int ldb, double* c, | |||
| lapack_int ldc, double* scale, | |||
| lapack_int* iwork, lapack_int liwork, | |||
| double* swork, lapack_int ldswork ) | |||
| { | |||
| lapack_int info = 0; | |||
| if( matrix_layout == LAPACK_COL_MAJOR ) { | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_dtrsyl3( &trana, &tranb, &isgn, &m, &n, a, &lda, b, &ldb, c, &ldc, | |||
| scale, iwork, &liwork, swork, &ldswork, &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| } else if( matrix_layout == LAPACK_ROW_MAJOR ) { | |||
| lapack_int lda_t = MAX(1,m); | |||
| lapack_int ldb_t = MAX(1,n); | |||
| lapack_int ldc_t = MAX(1,m); | |||
| double* a_t = NULL; | |||
| double* b_t = NULL; | |||
| double* c_t = NULL; | |||
| /* Check leading dimension(s) */ | |||
| if( lda < m ) { | |||
| info = -8; | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldb < n ) { | |||
| info = -10; | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldc < n ) { | |||
| info = -12; | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| /* Allocate memory for temporary array(s) */ | |||
| a_t = (double*)LAPACKE_malloc( sizeof(double) * lda_t * MAX(1,m) ); | |||
| if( a_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| b_t = (double*)LAPACKE_malloc( sizeof(double) * ldb_t * MAX(1,n) ); | |||
| if( b_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_1; | |||
| } | |||
| c_t = (double*)LAPACKE_malloc( sizeof(double) * ldc_t * MAX(1,n) ); | |||
| if( c_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_2; | |||
| } | |||
| /* Transpose input matrices */ | |||
| LAPACKE_dge_trans( matrix_layout, m, m, a, lda, a_t, lda_t ); | |||
| LAPACKE_dge_trans( matrix_layout, n, n, b, ldb, b_t, ldb_t ); | |||
| LAPACKE_dge_trans( matrix_layout, m, n, c, ldc, c_t, ldc_t ); | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_dtrsyl3( &trana, &tranb, &isgn, &m, &n, a_t, &lda_t, b_t, &ldb_t, | |||
| c_t, &ldc_t, scale, iwork, &liwork, swork, &ldswork, | |||
| &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| /* Transpose output matrices */ | |||
| LAPACKE_dge_trans( LAPACK_COL_MAJOR, m, n, c_t, ldc_t, c, ldc ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( c_t ); | |||
| exit_level_2: | |||
| LAPACKE_free( b_t ); | |||
| exit_level_1: | |||
| LAPACKE_free( a_t ); | |||
| exit_level_0: | |||
| if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3_work", info ); | |||
| } | |||
| } else { | |||
| info = -1; | |||
| LAPACKE_xerbla( "LAPACKE_dtrsyl3_work", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -48,7 +48,6 @@ lapack_int LAPACKE_sgesvdq( int matrix_layout, char joba, char jobp, | |||
| lapack_int lrwork = -1; | |||
| float* rwork = NULL; | |||
| float rwork_query; | |||
| lapack_int i; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_sgesvdq", -1 ); | |||
| return -1; | |||
| @@ -0,0 +1,68 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_strsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const float* a, lapack_int lda, const float* b, | |||
| lapack_int ldb, float* c, lapack_int ldc, | |||
| float* scale ) | |||
| { | |||
| lapack_int info = 0; | |||
| float swork_query[2]; | |||
| float* swork = NULL; | |||
| lapack_int ldswork = -1; | |||
| lapack_int swork_size = -1; | |||
| lapack_int iwork_query; | |||
| lapack_int* iwork = NULL; | |||
| lapack_int liwork = -1; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3", -1 ); | |||
| return -1; | |||
| } | |||
| #ifndef LAPACK_DISABLE_NAN_CHECK | |||
| if( LAPACKE_get_nancheck() ) { | |||
| /* Optionally check input matrices for NaNs */ | |||
| if( LAPACKE_sge_nancheck( matrix_layout, m, m, a, lda ) ) { | |||
| return -7; | |||
| } | |||
| if( LAPACKE_sge_nancheck( matrix_layout, n, n, b, ldb ) ) { | |||
| return -9; | |||
| } | |||
| if( LAPACKE_sge_nancheck( matrix_layout, m, n, c, ldc ) ) { | |||
| return -11; | |||
| } | |||
| } | |||
| #endif | |||
| /* Query optimal working array sizes */ | |||
| info = LAPACKE_strsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, lda, | |||
| b, ldb, c, ldc, scale, &iwork_query, liwork, | |||
| swork_query, ldswork ); | |||
| if( info != 0 ) { | |||
| goto exit_level_0; | |||
| } | |||
| ldswork = swork_query[0]; | |||
| swork_size = ldswork * swork_query[1]; | |||
| swork = (float*)LAPACKE_malloc( sizeof(float) * swork_size); | |||
| if( swork == NULL ) { | |||
| info = LAPACK_WORK_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| liwork = iwork_query; | |||
| iwork = (lapack_int*)LAPACKE_malloc( sizeof(lapack_int) * liwork ); | |||
| if ( iwork == NULL ) { | |||
| info = LAPACK_WORK_MEMORY_ERROR; | |||
| goto exit_level_1; | |||
| } | |||
| /* Call middle-level interface */ | |||
| info = LAPACKE_strsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, | |||
| lda, b, ldb, c, ldc, scale, iwork, liwork, | |||
| swork, ldswork ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( iwork ); | |||
| exit_level_1: | |||
| LAPACKE_free( swork ); | |||
| exit_level_0: | |||
| if( info == LAPACK_WORK_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -0,0 +1,86 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_strsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const float* a, lapack_int lda, | |||
| const float* b, lapack_int ldb, float* c, | |||
| lapack_int ldc, float* scale, | |||
| lapack_int* iwork, lapack_int liwork, | |||
| float* swork, lapack_int ldswork ) | |||
| { | |||
| lapack_int info = 0; | |||
| if( matrix_layout == LAPACK_COL_MAJOR ) { | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_strsyl3( &trana, &tranb, &isgn, &m, &n, a, &lda, b, &ldb, c, &ldc, | |||
| scale, iwork, &liwork, swork, &ldswork, &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| } else if( matrix_layout == LAPACK_ROW_MAJOR ) { | |||
| lapack_int lda_t = MAX(1,m); | |||
| lapack_int ldb_t = MAX(1,n); | |||
| lapack_int ldc_t = MAX(1,m); | |||
| float* a_t = NULL; | |||
| float* b_t = NULL; | |||
| float* c_t = NULL; | |||
| /* Check leading dimension(s) */ | |||
| if( lda < m ) { | |||
| info = -8; | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldb < n ) { | |||
| info = -10; | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldc < n ) { | |||
| info = -12; | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3_work", info ); | |||
| return info; | |||
| } | |||
| /* Allocate memory for temporary array(s) */ | |||
| a_t = (float*)LAPACKE_malloc( sizeof(float) * lda_t * MAX(1,m) ); | |||
| if( a_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| b_t = (float*)LAPACKE_malloc( sizeof(float) * ldb_t * MAX(1,n) ); | |||
| if( b_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_1; | |||
| } | |||
| c_t = (float*)LAPACKE_malloc( sizeof(float) * ldc_t * MAX(1,n) ); | |||
| if( c_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_2; | |||
| } | |||
| /* Transpose input matrices */ | |||
| LAPACKE_sge_trans( matrix_layout, m, m, a, lda, a_t, lda_t ); | |||
| LAPACKE_sge_trans( matrix_layout, n, n, b, ldb, b_t, ldb_t ); | |||
| LAPACKE_sge_trans( matrix_layout, m, n, c, ldc, c_t, ldc_t ); | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_strsyl3( &trana, &tranb, &isgn, &m, &n, a_t, &lda_t, b_t, &ldb_t, | |||
| c_t, &ldc_t, scale, iwork, &liwork, swork, &ldswork, | |||
| &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| /* Transpose output matrices */ | |||
| LAPACKE_sge_trans( LAPACK_COL_MAJOR, m, n, c_t, ldc_t, c, ldc ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( c_t ); | |||
| exit_level_2: | |||
| LAPACKE_free( b_t ); | |||
| exit_level_1: | |||
| LAPACKE_free( a_t ); | |||
| exit_level_0: | |||
| if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3_work", info ); | |||
| } | |||
| } else { | |||
| info = -1; | |||
| LAPACKE_xerbla( "LAPACKE_strsyl3_work", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -48,7 +48,6 @@ lapack_int LAPACKE_zgesvdq( int matrix_layout, char joba, char jobp, | |||
| lapack_int lrwork = -1; | |||
| double* rwork = NULL; | |||
| double rwork_query; | |||
| lapack_int i; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_zgesvdq", -1 ); | |||
| return -1; | |||
| @@ -0,0 +1,56 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_ztrsyl3( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_double* a, lapack_int lda, | |||
| const lapack_complex_double* b, lapack_int ldb, | |||
| lapack_complex_double* c, lapack_int ldc, | |||
| double* scale ) | |||
| { | |||
| lapack_int info = 0; | |||
| double swork_query[2]; | |||
| double* swork = NULL; | |||
| lapack_int ldswork = -1; | |||
| lapack_int swork_size = -1; | |||
| if( matrix_layout != LAPACK_COL_MAJOR && matrix_layout != LAPACK_ROW_MAJOR ) { | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3", -1 ); | |||
| return -1; | |||
| } | |||
| #ifndef LAPACK_DISABLE_NAN_CHECK | |||
| if( LAPACKE_get_nancheck() ) { | |||
| /* Optionally check input matrices for NaNs */ | |||
| if( LAPACKE_zge_nancheck( matrix_layout, m, m, a, lda ) ) { | |||
| return -7; | |||
| } | |||
| if( LAPACKE_zge_nancheck( matrix_layout, n, n, b, ldb ) ) { | |||
| return -9; | |||
| } | |||
| if( LAPACKE_zge_nancheck( matrix_layout, m, n, c, ldc ) ) { | |||
| return -11; | |||
| } | |||
| } | |||
| #endif | |||
| /* Query optimal working array sizes */ | |||
| info = LAPACKE_ztrsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, lda, | |||
| b, ldb, c, ldc, scale, swork_query, ldswork ); | |||
| if( info != 0 ) { | |||
| goto exit_level_0; | |||
| } | |||
| ldswork = swork_query[0]; | |||
| swork_size = ldswork * swork_query[1]; | |||
| swork = (double*)LAPACKE_malloc( sizeof(double) * swork_size); | |||
| if( swork == NULL ) { | |||
| info = LAPACK_WORK_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| /* Call middle-level interface */ | |||
| info = LAPACKE_ztrsyl3_work( matrix_layout, trana, tranb, isgn, m, n, a, | |||
| lda, b, ldb, c, ldc, scale, swork, ldswork ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( swork ); | |||
| exit_level_0: | |||
| if( info == LAPACK_WORK_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -0,0 +1,88 @@ | |||
| #include "lapacke_utils.h" | |||
| lapack_int LAPACKE_ztrsyl3_work( int matrix_layout, char trana, char tranb, | |||
| lapack_int isgn, lapack_int m, lapack_int n, | |||
| const lapack_complex_double* a, lapack_int lda, | |||
| const lapack_complex_double* b, lapack_int ldb, | |||
| lapack_complex_double* c, lapack_int ldc, | |||
| double* scale, double* swork, | |||
| lapack_int ldswork ) | |||
| { | |||
| lapack_int info = 0; | |||
| if( matrix_layout == LAPACK_COL_MAJOR ) { | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_ztrsyl3( &trana, &tranb, &isgn, &m, &n, a, &lda, b, &ldb, c, &ldc, | |||
| scale, swork, &ldswork, &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| } else if( matrix_layout == LAPACK_ROW_MAJOR ) { | |||
| lapack_int lda_t = MAX(1,m); | |||
| lapack_int ldb_t = MAX(1,n); | |||
| lapack_int ldc_t = MAX(1,m); | |||
| lapack_complex_double* a_t = NULL; | |||
| lapack_complex_double* b_t = NULL; | |||
| lapack_complex_double* c_t = NULL; | |||
| /* Check leading dimension(s) */ | |||
| if( lda < m ) { | |||
| info = -8; | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldb < n ) { | |||
| info = -10; | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| if( ldc < n ) { | |||
| info = -12; | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3_work", info ); | |||
| return info; | |||
| } | |||
| /* Allocate memory for temporary array(s) */ | |||
| a_t = (lapack_complex_double*) | |||
| LAPACKE_malloc( sizeof(lapack_complex_double) * lda_t * MAX(1,m) ); | |||
| if( a_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_0; | |||
| } | |||
| b_t = (lapack_complex_double*) | |||
| LAPACKE_malloc( sizeof(lapack_complex_double) * ldb_t * MAX(1,n) ); | |||
| if( b_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_1; | |||
| } | |||
| c_t = (lapack_complex_double*) | |||
| LAPACKE_malloc( sizeof(lapack_complex_double) * ldc_t * MAX(1,n) ); | |||
| if( c_t == NULL ) { | |||
| info = LAPACK_TRANSPOSE_MEMORY_ERROR; | |||
| goto exit_level_2; | |||
| } | |||
| /* Transpose input matrices */ | |||
| LAPACKE_zge_trans( matrix_layout, m, m, a, lda, a_t, lda_t ); | |||
| LAPACKE_zge_trans( matrix_layout, n, n, b, ldb, b_t, ldb_t ); | |||
| LAPACKE_zge_trans( matrix_layout, m, n, c, ldc, c_t, ldc_t ); | |||
| /* Call LAPACK function and adjust info */ | |||
| LAPACK_ztrsyl3( &trana, &tranb, &isgn, &m, &n, a_t, &lda_t, b_t, &ldb_t, | |||
| c_t, &ldc_t, scale, swork, &ldswork, &info ); | |||
| if( info < 0 ) { | |||
| info = info - 1; | |||
| } | |||
| /* Transpose output matrices */ | |||
| LAPACKE_zge_trans( LAPACK_COL_MAJOR, m, n, c_t, ldc_t, c, ldc ); | |||
| /* Release memory and exit */ | |||
| LAPACKE_free( c_t ); | |||
| exit_level_2: | |||
| LAPACKE_free( b_t ); | |||
| exit_level_1: | |||
| LAPACKE_free( a_t ); | |||
| exit_level_0: | |||
| if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3_work", info ); | |||
| } | |||
| } else { | |||
| info = -1; | |||
| LAPACKE_xerbla( "LAPACKE_ztrsyl3_work", info ); | |||
| } | |||
| return info; | |||
| } | |||
| @@ -207,7 +207,7 @@ SLASRC_O = \ | |||
| ssytrd_2stage.o ssytrd_sy2sb.o ssytrd_sb2st.o ssb2st_kernels.o \ | |||
| ssyevd_2stage.o ssyev_2stage.o ssyevx_2stage.o ssyevr_2stage.o \ | |||
| ssbev_2stage.o ssbevx_2stage.o ssbevd_2stage.o ssygv_2stage.o \ | |||
| sgesvdq.o | |||
| sgesvdq.o slarmm.o slatrs3.o strsyl3.o | |||
| endif | |||
| @@ -316,7 +316,7 @@ CLASRC_O = \ | |||
| chetrd_2stage.o chetrd_he2hb.o chetrd_hb2st.o chb2st_kernels.o \ | |||
| cheevd_2stage.o cheev_2stage.o cheevx_2stage.o cheevr_2stage.o \ | |||
| chbev_2stage.o chbevx_2stage.o chbevd_2stage.o chegv_2stage.o \ | |||
| cgesvdq.o | |||
| cgesvdq.o clatrs3.o ctrsyl3.o | |||
| endif | |||
| ifdef USEXBLAS | |||
| @@ -417,7 +417,7 @@ DLASRC_O = \ | |||
| dsytrd_2stage.o dsytrd_sy2sb.o dsytrd_sb2st.o dsb2st_kernels.o \ | |||
| dsyevd_2stage.o dsyev_2stage.o dsyevx_2stage.o dsyevr_2stage.o \ | |||
| dsbev_2stage.o dsbevx_2stage.o dsbevd_2stage.o dsygv_2stage.o \ | |||
| dgesvdq.o | |||
| dgesvdq.o dlarmm.o dlatrs3.o dtrsyl3.o | |||
| endif | |||
| ifdef USEXBLAS | |||
| @@ -526,7 +526,7 @@ ZLASRC_O = \ | |||
| zhetrd_2stage.o zhetrd_he2hb.o zhetrd_hb2st.o zhb2st_kernels.o \ | |||
| zheevd_2stage.o zheev_2stage.o zheevx_2stage.o zheevr_2stage.o \ | |||
| zhbev_2stage.o zhbevx_2stage.o zhbevd_2stage.o zhegv_2stage.o \ | |||
| zgesvdq.o | |||
| zgesvdq.o zlatrs3.o ztrsyl3.o | |||
| endif | |||
| ifdef USEXBLAS | |||
| @@ -0,0 +1,666 @@ | |||
| *> \brief \b CLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow. | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| * X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER DIAG, NORMIN, TRANS, UPLO | |||
| * INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL CNORM( * ), SCALE( * ), WORK( * ) | |||
| * COMPLEX A( LDA, * ), X( LDX, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CLATRS3 solves one of the triangular systems | |||
| *> | |||
| *> A * X = B * diag(scale), A**T * X = B * diag(scale), or | |||
| *> A**H * X = B * diag(scale) | |||
| *> | |||
| *> with scaling to prevent overflow. Here A is an upper or lower | |||
| *> triangular matrix, A**T denotes the transpose of A, A**H denotes the | |||
| *> conjugate transpose of A. X and B are n-by-nrhs matrices and scale | |||
| *> is an nrhs-element vector of scaling factors. A scaling factor scale(j) | |||
| *> is usually less than or equal to 1, chosen such that X(:,j) is less | |||
| *> than the overflow threshold. If the matrix A is singular (A(j,j) = 0 | |||
| *> for some j), then a non-trivial solution to A*X = 0 is returned. If | |||
| *> the system is so badly scaled that the solution cannot be represented | |||
| *> as (1/scale(k))*X(:,k), then x(:,k) = 0 and scale(k) is returned. | |||
| *> | |||
| *> This is a BLAS-3 version of LATRS for solving several right | |||
| *> hand sides simultaneously. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the matrix A is upper or lower triangular. | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] TRANS | |||
| *> \verbatim | |||
| *> TRANS is CHARACTER*1 | |||
| *> Specifies the operation applied to A. | |||
| *> = 'N': Solve A * x = s*b (No transpose) | |||
| *> = 'T': Solve A**T* x = s*b (Transpose) | |||
| *> = 'C': Solve A**T* x = s*b (Conjugate transpose) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] DIAG | |||
| *> \verbatim | |||
| *> DIAG is CHARACTER*1 | |||
| *> Specifies whether or not the matrix A is unit triangular. | |||
| *> = 'N': Non-unit triangular | |||
| *> = 'U': Unit triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NORMIN | |||
| *> \verbatim | |||
| *> NORMIN is CHARACTER*1 | |||
| *> Specifies whether CNORM has been set or not. | |||
| *> = 'Y': CNORM contains the column norms on entry | |||
| *> = 'N': CNORM is not set on entry. On exit, the norms will | |||
| *> be computed and stored in CNORM. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of columns of X. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> The triangular matrix A. If UPLO = 'U', the leading n by n | |||
| *> upper triangular part of the array A contains the upper | |||
| *> triangular matrix, and the strictly lower triangular part of | |||
| *> A is not referenced. If UPLO = 'L', the leading n by n lower | |||
| *> triangular part of the array A contains the lower triangular | |||
| *> matrix, and the strictly upper triangular part of A is not | |||
| *> referenced. If DIAG = 'U', the diagonal elements of A are | |||
| *> also not referenced and are assumed to be 1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X | |||
| *> \verbatim | |||
| *> X is COMPLEX array, dimension (LDX,NRHS) | |||
| *> On entry, the right hand side B of the triangular system. | |||
| *> On exit, X is overwritten by the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX | |||
| *> \verbatim | |||
| *> LDX is INTEGER | |||
| *> The leading dimension of the array X. LDX >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] SCALE | |||
| *> \verbatim | |||
| *> SCALE is REAL array, dimension (NRHS) | |||
| *> The scaling factor s(k) is for the triangular system | |||
| *> A * x(:,k) = s(k)*b(:,k) or A**T* x(:,k) = s(k)*b(:,k). | |||
| *> If SCALE = 0, the matrix A is singular or badly scaled. | |||
| *> If A(j,j) = 0 is encountered, a non-trivial vector x(:,k) | |||
| *> that is an exact or approximate solution to A*x(:,k) = 0 | |||
| *> is returned. If the system so badly scaled that solution | |||
| *> cannot be presented as x(:,k) * 1/s(k), then x(:,k) = 0 | |||
| *> is returned. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] CNORM | |||
| *> \verbatim | |||
| *> CNORM is REAL array, dimension (N) | |||
| *> | |||
| *> If NORMIN = 'Y', CNORM is an input argument and CNORM(j) | |||
| *> contains the norm of the off-diagonal part of the j-th column | |||
| *> of A. If TRANS = 'N', CNORM(j) must be greater than or equal | |||
| *> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) | |||
| *> must be greater than or equal to the 1-norm. | |||
| *> | |||
| *> If NORMIN = 'N', CNORM is an output argument and CNORM(j) | |||
| *> returns the 1-norm of the offdiagonal part of the j-th column | |||
| *> of A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is REAL array, dimension (LWORK). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal size of | |||
| *> WORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> LWORK is INTEGER | |||
| *> LWORK >= MAX(1, 2*NBA * MAX(NBA, MIN(NRHS, 32)), where | |||
| *> NBA = (N + NB - 1)/NB and NB is the optimal block size. | |||
| *> | |||
| *> If LWORK = -1, then a workspace query is assumed; the routine | |||
| *> only calculates the optimal dimensions of the WORK array, returns | |||
| *> this value as the first entry of the WORK array, and no error | |||
| *> message related to LWORK is issued by XERBLA. | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \ingroup doubleOTHERauxiliary | |||
| *> \par Further Details: | |||
| * ===================== | |||
| * \verbatim | |||
| * The algorithm follows the structure of a block triangular solve. | |||
| * The diagonal block is solved with a call to the robust the triangular | |||
| * solver LATRS for every right-hand side RHS = 1, ..., NRHS | |||
| * op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ), | |||
| * where op( A ) = A or op( A ) = A**T or op( A ) = A**H. | |||
| * The linear block updates operate on block columns of X, | |||
| * B( I, K ) - op(A( I, J )) * X( J, K ) | |||
| * and use GEMM. To avoid overflow in the linear block update, the worst case | |||
| * growth is estimated. For every RHS, a scale factor s <= 1.0 is computed | |||
| * such that | |||
| * || s * B( I, RHS )||_oo | |||
| * + || op(A( I, J )) ||_oo * || s * X( J, RHS ) ||_oo <= Overflow threshold | |||
| * | |||
| * Once all columns of a block column have been rescaled (BLAS-1), the linear | |||
| * update is executed with GEMM without overflow. | |||
| * | |||
| * To limit rescaling, local scale factors track the scaling of column segments. | |||
| * There is one local scale factor s( I, RHS ) per block row I = 1, ..., NBA | |||
| * per right-hand side column RHS = 1, ..., NRHS. The global scale factor | |||
| * SCALE( RHS ) is chosen as the smallest local scale factor s( I, RHS ) | |||
| * I = 1, ..., NBA. | |||
| * A triangular solve op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ) | |||
| * updates the local scale factor s( J, RHS ) := s( J, RHS ) * SCALOC. The | |||
| * linear update of potentially inconsistently scaled vector segments | |||
| * s( I, RHS ) * b( I, RHS ) - op(A( I, J )) * ( s( J, RHS )* x( J, RHS ) ) | |||
| * computes a consistent scaling SCAMIN = MIN( s(I, RHS ), s(J, RHS) ) and, | |||
| * if necessary, rescales the blocks prior to calling GEMM. | |||
| * | |||
| * \endverbatim | |||
| * ===================================================================== | |||
| * References: | |||
| * C. C. Kjelgaard Mikkelsen, A. B. Schwarz and L. Karlsson (2019). | |||
| * Parallel robust solution of triangular linear systems. Concurrency | |||
| * and Computation: Practice and Experience, 31(19), e5064. | |||
| * | |||
| * Contributor: | |||
| * Angelika Schwarz, Umea University, Sweden. | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| IMPLICIT NONE | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER DIAG, TRANS, NORMIN, UPLO | |||
| INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| COMPLEX A( LDA, * ), X( LDX, * ) | |||
| REAL CNORM( * ), SCALE( * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| COMPLEX CZERO, CONE | |||
| PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ) ) | |||
| PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) ) | |||
| INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN | |||
| PARAMETER ( NRHSMIN = 2, NBRHS = 32 ) | |||
| PARAMETER ( NBMIN = 8, NBMAX = 64 ) | |||
| * .. | |||
| * .. Local Arrays .. | |||
| REAL W( NBMAX ), XNRM( NBRHS ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER | |||
| INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J, | |||
| $ JFIRST, JINC, JLAST, J1, J2, K, KK, K1, K2, | |||
| $ LANRM, LDS, LSCALE, NB, NBA, NBX, RHS | |||
| REAL ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC, | |||
| $ SCAMIN, SMLNUM, TMAX | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| REAL SLAMCH, CLANGE, SLARMM | |||
| EXTERNAL ILAENV, LSAME, SLAMCH, CLANGE, SLARMM | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLATRS, CSSCAL, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, MIN | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| NOTRAN = LSAME( TRANS, 'N' ) | |||
| NOUNIT = LSAME( DIAG, 'N' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| * | |||
| * Partition A and X into blocks. | |||
| * | |||
| NB = MAX( NBMIN, ILAENV( 1, 'CLATRS', '', N, N, -1, -1 ) ) | |||
| NB = MIN( NBMAX, NB ) | |||
| NBA = MAX( 1, (N + NB - 1) / NB ) | |||
| NBX = MAX( 1, (NRHS + NBRHS - 1) / NBRHS ) | |||
| * | |||
| * Compute the workspace | |||
| * | |||
| * The workspace comprises two parts. | |||
| * The first part stores the local scale factors. Each simultaneously | |||
| * computed right-hand side requires one local scale factor per block | |||
| * row. WORK( I + KK * LDS ) is the scale factor of the vector | |||
| * segment associated with the I-th block row and the KK-th vector | |||
| * in the block column. | |||
| LSCALE = NBA * MAX( NBA, MIN( NRHS, NBRHS ) ) | |||
| LDS = NBA | |||
| * The second part stores upper bounds of the triangular A. There are | |||
| * a total of NBA x NBA blocks, of which only the upper triangular | |||
| * part or the lower triangular part is referenced. The upper bound of | |||
| * the block A( I, J ) is stored as WORK( AWRK + I + J * NBA ). | |||
| LANRM = NBA * NBA | |||
| AWRK = LSCALE | |||
| WORK( 1 ) = LSCALE + LANRM | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. | |||
| $ LSAME( TRANS, 'C' ) ) THEN | |||
| INFO = -2 | |||
| ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN | |||
| INFO = -3 | |||
| ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT. | |||
| $ LSAME( NORMIN, 'N' ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LDX.LT.MAX( 1, N ) ) THEN | |||
| INFO = -10 | |||
| ELSE IF( .NOT.LQUERY .AND. LWORK.LT.WORK( 1 ) ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CLATRS3', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize scaling factors | |||
| * | |||
| DO KK = 1, NRHS | |||
| SCALE( KK ) = ONE | |||
| END DO | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( MIN( N, NRHS ).EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Determine machine dependent constant to control overflow. | |||
| * | |||
| BIGNUM = SLAMCH( 'Overflow' ) | |||
| SMLNUM = SLAMCH( 'Safe Minimum' ) | |||
| * | |||
| * Use unblocked code for small problems | |||
| * | |||
| IF( NRHS.LT.NRHSMIN ) THEN | |||
| CALL CLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X( 1, 1 ), | |||
| $ SCALE( 1 ), CNORM, INFO ) | |||
| DO K = 2, NRHS | |||
| CALL CLATRS( UPLO, TRANS, DIAG, 'Y', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute norms of blocks of A excluding diagonal blocks and find | |||
| * the block with the largest norm TMAX. | |||
| * | |||
| TMAX = ZERO | |||
| DO J = 1, NBA | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| IF ( UPPER ) THEN | |||
| IFIRST = 1 | |||
| ILAST = J - 1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| END IF | |||
| DO I = IFIRST, ILAST | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Compute upper bound of A( I1:I2-1, J1:J2-1 ). | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| ANRM = CLANGE( 'I', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + I+(J-1)*NBA ) = ANRM | |||
| ELSE | |||
| ANRM = CLANGE( '1', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + J+(I-1)*NBA ) = ANRM | |||
| END IF | |||
| TMAX = MAX( TMAX, ANRM ) | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( .NOT. TMAX.LE.SLAMCH('Overflow') ) THEN | |||
| * | |||
| * Some matrix entries have huge absolute value. At least one upper | |||
| * bound norm( A(I1:I2-1, J1:J2-1), 'I') is not a valid floating-point | |||
| * number, either due to overflow in LANGE or due to Inf in A. | |||
| * Fall back to LATRS. Set normin = 'N' for every right-hand side to | |||
| * force computation of TSCAL in LATRS to avoid the likely overflow | |||
| * in the computation of the column norms CNORM. | |||
| * | |||
| DO K = 1, NRHS | |||
| CALL CLATRS( UPLO, TRANS, DIAG, 'N', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Every right-hand side requires workspace to store NBA local scale | |||
| * factors. To save workspace, X is computed successively in block columns | |||
| * of width NBRHS, requiring a total of NBA x NBRHS space. If sufficient | |||
| * workspace is available, larger values of NBRHS or NBRHS = NRHS are viable. | |||
| DO K = 1, NBX | |||
| * Loop over block columns (index = K) of X and, for column-wise scalings, | |||
| * over individual columns (index = KK). | |||
| * K1: column index of the first column in X( J, K ) | |||
| * K2: column index of the first column in X( J, K+1 ) | |||
| * so the K2 - K1 is the column count of the block X( J, K ) | |||
| K1 = (K-1)*NBRHS + 1 | |||
| K2 = MIN( K*NBRHS, NRHS ) + 1 | |||
| * | |||
| * Initialize local scaling factors of current block column X( J, K ) | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| DO I = 1, NBA | |||
| WORK( I+KK*LDS ) = ONE | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * Solve A * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| ELSE | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Solve op(A) * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * where op(A) = A**T or op(A) = A**H | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| ELSE | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| END IF | |||
| END IF | |||
| DO J = JFIRST, JLAST, JINC | |||
| * J1: row index of the first row in A( J, J ) | |||
| * J2: row index of the first row in A( J+1, J+1 ) | |||
| * so that J2 - J1 is the row count of the block A( J, J ) | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| * | |||
| * Solve op(A( J, J )) * X( J, RHS ) = SCALOC * B( J, RHS ) | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( KK.EQ.1 ) THEN | |||
| CALL CLATRS( UPLO, TRANS, DIAG, 'N', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| ELSE | |||
| CALL CLATRS( UPLO, TRANS, DIAG, 'Y', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| END IF | |||
| * Find largest absolute value entry in the vector segment | |||
| * X( J1:J2-1, RHS ) as an upper bound for the worst case | |||
| * growth in the linear updates. | |||
| XNRM( KK ) = CLANGE( 'I', J2-J1, 1, X( J1, RHS ), | |||
| $ LDX, W ) | |||
| * | |||
| IF( SCALOC .EQ. ZERO ) THEN | |||
| * LATRS found that A is singular through A(j,j) = 0. | |||
| * Reset the computation x(1:n) = 0, x(j) = 1, SCALE = 0 | |||
| * and compute op(A)*x = 0. Note that X(J1:J2-1, KK) is | |||
| * set by LATRS. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, J1-1 | |||
| X( II, KK ) = CZERO | |||
| END DO | |||
| DO II = J2, N | |||
| X( II, KK ) = CZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| ELSE IF( SCALOC*WORK( J+KK*LDS ) .EQ. ZERO ) THEN | |||
| * LATRS computed a valid scale factor, but combined with | |||
| * the current scaling the solution does not have a | |||
| * scale factor > 0. | |||
| * | |||
| * Set WORK( J+KK*LDS ) to smallest valid scale | |||
| * factor and increase SCALOC accordingly. | |||
| SCAL = WORK( J+KK*LDS ) / SMLNUM | |||
| SCALOC = SCALOC * SCAL | |||
| WORK( J+KK*LDS ) = SMLNUM | |||
| * If LATRS overestimated the growth, x may be | |||
| * rescaled to preserve a valid combined scale | |||
| * factor WORK( J, KK ) > 0. | |||
| RSCAL = ONE / SCALOC | |||
| IF( XNRM( KK )*RSCAL .LE. BIGNUM ) THEN | |||
| XNRM( KK ) = XNRM( KK ) * RSCAL | |||
| CALL CSSCAL( J2-J1, RSCAL, X( J1, RHS ), 1 ) | |||
| SCALOC = ONE | |||
| ELSE | |||
| * The system op(A) * x = b is badly scaled and its | |||
| * solution cannot be represented as (1/scale) * x. | |||
| * Set x to zero. This approach deviates from LATRS | |||
| * where a completely meaningless non-zero vector | |||
| * is returned that is not a solution to op(A) * x = b. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, N | |||
| X( II, KK ) = CZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| END IF | |||
| END IF | |||
| SCALOC = SCALOC * WORK( J+KK*LDS ) | |||
| WORK( J+KK*LDS ) = SCALOC | |||
| END DO | |||
| * | |||
| * Linear block updates | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| IF( UPPER ) THEN | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| END IF | |||
| ELSE | |||
| IF( UPPER ) THEN | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| ELSE | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| END IF | |||
| END IF | |||
| * | |||
| DO I = IFIRST, ILAST, IINC | |||
| * I1: row index of the first column in X( I, K ) | |||
| * I2: row index of the first column in X( I+1, K ) | |||
| * so the I2 - I1 is the row count of the block X( I, K ) | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Prepare the linear update to be executed with GEMM. | |||
| * For each column, compute a consistent scaling, a | |||
| * scaling factor to survive the linear update, and | |||
| * rescale the column segments, if necesssary. Then | |||
| * the linear update is safely executed. | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| * Compute consistent scaling | |||
| SCAMIN = MIN( WORK( I+KK*LDS), WORK( J+KK*LDS ) ) | |||
| * | |||
| * Compute scaling factor to survive the linear update | |||
| * simulating consistent scaling. | |||
| * | |||
| BNRM = CLANGE( 'I', I2-I1, 1, X( I1, RHS ), LDX, W ) | |||
| BNRM = BNRM*( SCAMIN / WORK( I+KK*LDS ) ) | |||
| XNRM( KK ) = XNRM( KK )*( SCAMIN / WORK( J+KK*LDS) ) | |||
| ANRM = WORK( AWRK + I+(J-1)*NBA ) | |||
| SCALOC = SLARMM( ANRM, XNRM( KK ), BNRM ) | |||
| * | |||
| * Simultaneously apply the robust update factor and the | |||
| * consistency scaling factor to X( I, KK ) and X( J, KK ). | |||
| * | |||
| SCAL = ( SCAMIN / WORK( I+KK*LDS) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL CSSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| WORK( I+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| * | |||
| SCAL = ( SCAMIN / WORK( J+KK*LDS ) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL CSSCAL( J2-J1, SCAL, X( J1, RHS ), 1 ) | |||
| WORK( J+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J ) * X( J, K ) | |||
| * | |||
| CALL CGEMM( 'N', 'N', I2-I1, K2-K1, J2-J1, -CONE, | |||
| $ A( I1, J1 ), LDA, X( J1, K1 ), LDX, | |||
| $ CONE, X( I1, K1 ), LDX ) | |||
| ELSE IF( LSAME( TRANS, 'T' ) ) THEN | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J )**T * X( J, K ) | |||
| * | |||
| CALL CGEMM( 'T', 'N', I2-I1, K2-K1, J2-J1, -CONE, | |||
| $ A( J1, I1 ), LDA, X( J1, K1 ), LDX, | |||
| $ CONE, X( I1, K1 ), LDX ) | |||
| ELSE | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J )**H * X( J, K ) | |||
| * | |||
| CALL CGEMM( 'C', 'N', I2-I1, K2-K1, J2-J1, -CONE, | |||
| $ A( J1, I1 ), LDA, X( J1, K1 ), LDX, | |||
| $ CONE, X( I1, K1 ), LDX ) | |||
| END IF | |||
| END DO | |||
| END DO | |||
| * | |||
| * Reduce local scaling factors | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| DO I = 1, NBA | |||
| SCALE( RHS ) = MIN( SCALE( RHS ), WORK( I+KK*LDS ) ) | |||
| END DO | |||
| END DO | |||
| * | |||
| * Realize consistent scaling | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( SCALE( RHS ).NE.ONE .AND. SCALE( RHS ).NE. ZERO ) THEN | |||
| DO I = 1, NBA | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| SCAL = SCALE( RHS ) / WORK( I+KK*LDS ) | |||
| IF( SCAL.NE.ONE ) | |||
| $ CALL CSSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| END DO | |||
| END IF | |||
| END DO | |||
| END DO | |||
| RETURN | |||
| * | |||
| * End of CLATRS3 | |||
| * | |||
| END | |||
| @@ -0,0 +1,605 @@ | |||
| #include <math.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <complex.h> | |||
| #ifdef complex | |||
| #undef complex | |||
| #endif | |||
| #ifdef I | |||
| #undef I | |||
| #endif | |||
| #if defined(_WIN64) | |||
| typedef long long BLASLONG; | |||
| typedef unsigned long long BLASULONG; | |||
| #else | |||
| typedef long BLASLONG; | |||
| typedef unsigned long BLASULONG; | |||
| #endif | |||
| #ifdef LAPACK_ILP64 | |||
| typedef BLASLONG blasint; | |||
| #if defined(_WIN64) | |||
| #define blasabs(x) llabs(x) | |||
| #else | |||
| #define blasabs(x) labs(x) | |||
| #endif | |||
| #else | |||
| typedef int blasint; | |||
| #define blasabs(x) abs(x) | |||
| #endif | |||
| typedef blasint integer; | |||
| typedef unsigned int uinteger; | |||
| typedef char *address; | |||
| typedef short int shortint; | |||
| typedef float real; | |||
| typedef double doublereal; | |||
| typedef struct { real r, i; } complex; | |||
| typedef struct { doublereal r, i; } doublecomplex; | |||
| #ifdef _MSC_VER | |||
| static inline _Fcomplex Cf(complex *z) {_Fcomplex zz={z->r , z->i}; return zz;} | |||
| static inline _Dcomplex Cd(doublecomplex *z) {_Dcomplex zz={z->r , z->i};return zz;} | |||
| static inline _Fcomplex * _pCf(complex *z) {return (_Fcomplex*)z;} | |||
| static inline _Dcomplex * _pCd(doublecomplex *z) {return (_Dcomplex*)z;} | |||
| #else | |||
| static inline _Complex float Cf(complex *z) {return z->r + z->i*_Complex_I;} | |||
| static inline _Complex double Cd(doublecomplex *z) {return z->r + z->i*_Complex_I;} | |||
| static inline _Complex float * _pCf(complex *z) {return (_Complex float*)z;} | |||
| static inline _Complex double * _pCd(doublecomplex *z) {return (_Complex double*)z;} | |||
| #endif | |||
| #define pCf(z) (*_pCf(z)) | |||
| #define pCd(z) (*_pCd(z)) | |||
| typedef int logical; | |||
| typedef short int shortlogical; | |||
| typedef char logical1; | |||
| typedef char integer1; | |||
| #define TRUE_ (1) | |||
| #define FALSE_ (0) | |||
| /* Extern is for use with -E */ | |||
| #ifndef Extern | |||
| #define Extern extern | |||
| #endif | |||
| /* I/O stuff */ | |||
| typedef int flag; | |||
| typedef int ftnlen; | |||
| typedef int ftnint; | |||
| /*external read, write*/ | |||
| typedef struct | |||
| { flag cierr; | |||
| ftnint ciunit; | |||
| flag ciend; | |||
| char *cifmt; | |||
| ftnint cirec; | |||
| } cilist; | |||
| /*internal read, write*/ | |||
| typedef struct | |||
| { flag icierr; | |||
| char *iciunit; | |||
| flag iciend; | |||
| char *icifmt; | |||
| ftnint icirlen; | |||
| ftnint icirnum; | |||
| } icilist; | |||
| /*open*/ | |||
| typedef struct | |||
| { flag oerr; | |||
| ftnint ounit; | |||
| char *ofnm; | |||
| ftnlen ofnmlen; | |||
| char *osta; | |||
| char *oacc; | |||
| char *ofm; | |||
| ftnint orl; | |||
| char *oblnk; | |||
| } olist; | |||
| /*close*/ | |||
| typedef struct | |||
| { flag cerr; | |||
| ftnint cunit; | |||
| char *csta; | |||
| } cllist; | |||
| /*rewind, backspace, endfile*/ | |||
| typedef struct | |||
| { flag aerr; | |||
| ftnint aunit; | |||
| } alist; | |||
| /* inquire */ | |||
| typedef struct | |||
| { flag inerr; | |||
| ftnint inunit; | |||
| char *infile; | |||
| ftnlen infilen; | |||
| ftnint *inex; /*parameters in standard's order*/ | |||
| ftnint *inopen; | |||
| ftnint *innum; | |||
| ftnint *innamed; | |||
| char *inname; | |||
| ftnlen innamlen; | |||
| char *inacc; | |||
| ftnlen inacclen; | |||
| char *inseq; | |||
| ftnlen inseqlen; | |||
| char *indir; | |||
| ftnlen indirlen; | |||
| char *infmt; | |||
| ftnlen infmtlen; | |||
| char *inform; | |||
| ftnint informlen; | |||
| char *inunf; | |||
| ftnlen inunflen; | |||
| ftnint *inrecl; | |||
| ftnint *innrec; | |||
| char *inblank; | |||
| ftnlen inblanklen; | |||
| } inlist; | |||
| #define VOID void | |||
| union Multitype { /* for multiple entry points */ | |||
| integer1 g; | |||
| shortint h; | |||
| integer i; | |||
| /* longint j; */ | |||
| real r; | |||
| doublereal d; | |||
| complex c; | |||
| doublecomplex z; | |||
| }; | |||
| typedef union Multitype Multitype; | |||
| struct Vardesc { /* for Namelist */ | |||
| char *name; | |||
| char *addr; | |||
| ftnlen *dims; | |||
| int type; | |||
| }; | |||
| typedef struct Vardesc Vardesc; | |||
| struct Namelist { | |||
| char *name; | |||
| Vardesc **vars; | |||
| int nvars; | |||
| }; | |||
| typedef struct Namelist Namelist; | |||
| #define abs(x) ((x) >= 0 ? (x) : -(x)) | |||
| #define dabs(x) (fabs(x)) | |||
| #define f2cmin(a,b) ((a) <= (b) ? (a) : (b)) | |||
| #define f2cmax(a,b) ((a) >= (b) ? (a) : (b)) | |||
| #define dmin(a,b) (f2cmin(a,b)) | |||
| #define dmax(a,b) (f2cmax(a,b)) | |||
| #define bit_test(a,b) ((a) >> (b) & 1) | |||
| #define bit_clear(a,b) ((a) & ~((uinteger)1 << (b))) | |||
| #define bit_set(a,b) ((a) | ((uinteger)1 << (b))) | |||
| #define abort_() { sig_die("Fortran abort routine called", 1); } | |||
| #define c_abs(z) (cabsf(Cf(z))) | |||
| #define c_cos(R,Z) { pCf(R)=ccos(Cf(Z)); } | |||
| #ifdef _MSC_VER | |||
| #define c_div(c, a, b) {Cf(c)._Val[0] = (Cf(a)._Val[0]/Cf(b)._Val[0]); Cf(c)._Val[1]=(Cf(a)._Val[1]/Cf(b)._Val[1]);} | |||
| #define z_div(c, a, b) {Cd(c)._Val[0] = (Cd(a)._Val[0]/Cd(b)._Val[0]); Cd(c)._Val[1]=(Cd(a)._Val[1]/Cd(b)._Val[1]);} | |||
| #else | |||
| #define c_div(c, a, b) {pCf(c) = Cf(a)/Cf(b);} | |||
| #define z_div(c, a, b) {pCd(c) = Cd(a)/Cd(b);} | |||
| #endif | |||
| #define c_exp(R, Z) {pCf(R) = cexpf(Cf(Z));} | |||
| #define c_log(R, Z) {pCf(R) = clogf(Cf(Z));} | |||
| #define c_sin(R, Z) {pCf(R) = csinf(Cf(Z));} | |||
| //#define c_sqrt(R, Z) {*(R) = csqrtf(Cf(Z));} | |||
| #define c_sqrt(R, Z) {pCf(R) = csqrtf(Cf(Z));} | |||
| #define d_abs(x) (fabs(*(x))) | |||
| #define d_acos(x) (acos(*(x))) | |||
| #define d_asin(x) (asin(*(x))) | |||
| #define d_atan(x) (atan(*(x))) | |||
| #define d_atn2(x, y) (atan2(*(x),*(y))) | |||
| #define d_cnjg(R, Z) { pCd(R) = conj(Cd(Z)); } | |||
| #define r_cnjg(R, Z) { pCf(R) = conjf(Cf(Z)); } | |||
| #define d_cos(x) (cos(*(x))) | |||
| #define d_cosh(x) (cosh(*(x))) | |||
| #define d_dim(__a, __b) ( *(__a) > *(__b) ? *(__a) - *(__b) : 0.0 ) | |||
| #define d_exp(x) (exp(*(x))) | |||
| #define d_imag(z) (cimag(Cd(z))) | |||
| #define r_imag(z) (cimagf(Cf(z))) | |||
| #define d_int(__x) (*(__x)>0 ? floor(*(__x)) : -floor(- *(__x))) | |||
| #define r_int(__x) (*(__x)>0 ? floor(*(__x)) : -floor(- *(__x))) | |||
| #define d_lg10(x) ( 0.43429448190325182765 * log(*(x)) ) | |||
| #define r_lg10(x) ( 0.43429448190325182765 * log(*(x)) ) | |||
| #define d_log(x) (log(*(x))) | |||
| #define d_mod(x, y) (fmod(*(x), *(y))) | |||
| #define u_nint(__x) ((__x)>=0 ? floor((__x) + .5) : -floor(.5 - (__x))) | |||
| #define d_nint(x) u_nint(*(x)) | |||
| #define u_sign(__a,__b) ((__b) >= 0 ? ((__a) >= 0 ? (__a) : -(__a)) : -((__a) >= 0 ? (__a) : -(__a))) | |||
| #define d_sign(a,b) u_sign(*(a),*(b)) | |||
| #define r_sign(a,b) u_sign(*(a),*(b)) | |||
| #define d_sin(x) (sin(*(x))) | |||
| #define d_sinh(x) (sinh(*(x))) | |||
| #define d_sqrt(x) (sqrt(*(x))) | |||
| #define d_tan(x) (tan(*(x))) | |||
| #define d_tanh(x) (tanh(*(x))) | |||
| #define i_abs(x) abs(*(x)) | |||
| #define i_dnnt(x) ((integer)u_nint(*(x))) | |||
| #define i_len(s, n) (n) | |||
| #define i_nint(x) ((integer)u_nint(*(x))) | |||
| #define i_sign(a,b) ((integer)u_sign((integer)*(a),(integer)*(b))) | |||
| #define pow_dd(ap, bp) ( pow(*(ap), *(bp))) | |||
| #define pow_si(B,E) spow_ui(*(B),*(E)) | |||
| #define pow_ri(B,E) spow_ui(*(B),*(E)) | |||
| #define pow_di(B,E) dpow_ui(*(B),*(E)) | |||
| #define pow_zi(p, a, b) {pCd(p) = zpow_ui(Cd(a), *(b));} | |||
| #define pow_ci(p, a, b) {pCf(p) = cpow_ui(Cf(a), *(b));} | |||
| #define pow_zz(R,A,B) {pCd(R) = cpow(Cd(A),*(B));} | |||
| #define s_cat(lpp, rpp, rnp, np, llp) { ftnlen i, nc, ll; char *f__rp, *lp; ll = (llp); lp = (lpp); for(i=0; i < (int)*(np); ++i) { nc = ll; if((rnp)[i] < nc) nc = (rnp)[i]; ll -= nc; f__rp = (rpp)[i]; while(--nc >= 0) *lp++ = *(f__rp)++; } while(--ll >= 0) *lp++ = ' '; } | |||
| #define s_cmp(a,b,c,d) ((integer)strncmp((a),(b),f2cmin((c),(d)))) | |||
| #define s_copy(A,B,C,D) { int __i,__m; for (__i=0, __m=f2cmin((C),(D)); __i<__m && (B)[__i] != 0; ++__i) (A)[__i] = (B)[__i]; } | |||
| #define sig_die(s, kill) { exit(1); } | |||
| #define s_stop(s, n) {exit(0);} | |||
| static char junk[] = "\n@(#)LIBF77 VERSION 19990503\n"; | |||
| #define z_abs(z) (cabs(Cd(z))) | |||
| #define z_exp(R, Z) {pCd(R) = cexp(Cd(Z));} | |||
| #define z_sqrt(R, Z) {pCd(R) = csqrt(Cd(Z));} | |||
| #define myexit_() break; | |||
| #define mycycle_() continue; | |||
| #define myceiling_(w) {ceil(w)} | |||
| #define myhuge_(w) {HUGE_VAL} | |||
| //#define mymaxloc_(w,s,e,n) {if (sizeof(*(w)) == sizeof(double)) dmaxloc_((w),*(s),*(e),n); else dmaxloc_((w),*(s),*(e),n);} | |||
| #define mymaxloc_(w,s,e,n) dmaxloc_(w,*(s),*(e),n) | |||
| #define myexp_(w) my_expfunc(w) | |||
| static int my_expfunc(double *x) {int e; (void)frexp(*x,&e); return e;} | |||
| /* procedure parameter types for -A and -C++ */ | |||
| #define F2C_proc_par_types 1 | |||
| #ifdef __cplusplus | |||
| typedef logical (*L_fp)(...); | |||
| #else | |||
| typedef logical (*L_fp)(); | |||
| #endif | |||
| static float spow_ui(float x, integer n) { | |||
| float pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| static double dpow_ui(double x, integer n) { | |||
| double pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| #ifdef _MSC_VER | |||
| static _Fcomplex cpow_ui(complex x, integer n) { | |||
| complex pow={1.0,0.0}; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x.r = 1/x.r, x.i=1/x.i; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow.r *= x.r, pow.i *= x.i; | |||
| if(u >>= 1) x.r *= x.r, x.i *= x.i; | |||
| else break; | |||
| } | |||
| } | |||
| _Fcomplex p={pow.r, pow.i}; | |||
| return p; | |||
| } | |||
| #else | |||
| static _Complex float cpow_ui(_Complex float x, integer n) { | |||
| _Complex float pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| #endif | |||
| #ifdef _MSC_VER | |||
| static _Dcomplex zpow_ui(_Dcomplex x, integer n) { | |||
| _Dcomplex pow={1.0,0.0}; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x._Val[0] = 1/x._Val[0], x._Val[1] =1/x._Val[1]; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow._Val[0] *= x._Val[0], pow._Val[1] *= x._Val[1]; | |||
| if(u >>= 1) x._Val[0] *= x._Val[0], x._Val[1] *= x._Val[1]; | |||
| else break; | |||
| } | |||
| } | |||
| _Dcomplex p = {pow._Val[0], pow._Val[1]}; | |||
| return p; | |||
| } | |||
| #else | |||
| static _Complex double zpow_ui(_Complex double x, integer n) { | |||
| _Complex double pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| #endif | |||
| static integer pow_ii(integer x, integer n) { | |||
| integer pow; unsigned long int u; | |||
| if (n <= 0) { | |||
| if (n == 0 || x == 1) pow = 1; | |||
| else if (x != -1) pow = x == 0 ? 1/x : 0; | |||
| else n = -n; | |||
| } | |||
| if ((n > 0) || !(n == 0 || x == 1 || x != -1)) { | |||
| u = n; | |||
| for(pow = 1; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| static integer dmaxloc_(double *w, integer s, integer e, integer *n) | |||
| { | |||
| double m; integer i, mi; | |||
| for(m=w[s-1], mi=s, i=s+1; i<=e; i++) | |||
| if (w[i-1]>m) mi=i ,m=w[i-1]; | |||
| return mi-s+1; | |||
| } | |||
| static integer smaxloc_(float *w, integer s, integer e, integer *n) | |||
| { | |||
| float m; integer i, mi; | |||
| for(m=w[s-1], mi=s, i=s+1; i<=e; i++) | |||
| if (w[i-1]>m) mi=i ,m=w[i-1]; | |||
| return mi-s+1; | |||
| } | |||
| static inline void cdotc_(complex *z, integer *n_, complex *x, integer *incx_, complex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Fcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conjf(Cf(&x[i]))._Val[0] * Cf(&y[i])._Val[0]; | |||
| zdotc._Val[1] += conjf(Cf(&x[i]))._Val[1] * Cf(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conjf(Cf(&x[i*incx]))._Val[0] * Cf(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += conjf(Cf(&x[i*incx]))._Val[1] * Cf(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex float zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conjf(Cf(&x[i])) * Cf(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conjf(Cf(&x[i*incx])) * Cf(&y[i*incy]); | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #endif | |||
| static inline void zdotc_(doublecomplex *z, integer *n_, doublecomplex *x, integer *incx_, doublecomplex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Dcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conj(Cd(&x[i]))._Val[0] * Cd(&y[i])._Val[0]; | |||
| zdotc._Val[1] += conj(Cd(&x[i]))._Val[1] * Cd(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conj(Cd(&x[i*incx]))._Val[0] * Cd(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += conj(Cd(&x[i*incx]))._Val[1] * Cd(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex double zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conj(Cd(&x[i])) * Cd(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conj(Cd(&x[i*incx])) * Cd(&y[i*incy]); | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #endif | |||
| static inline void cdotu_(complex *z, integer *n_, complex *x, integer *incx_, complex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Fcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cf(&x[i])._Val[0] * Cf(&y[i])._Val[0]; | |||
| zdotc._Val[1] += Cf(&x[i])._Val[1] * Cf(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cf(&x[i*incx])._Val[0] * Cf(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += Cf(&x[i*incx])._Val[1] * Cf(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex float zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cf(&x[i]) * Cf(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cf(&x[i*incx]) * Cf(&y[i*incy]); | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #endif | |||
| static inline void zdotu_(doublecomplex *z, integer *n_, doublecomplex *x, integer *incx_, doublecomplex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Dcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cd(&x[i])._Val[0] * Cd(&y[i])._Val[0]; | |||
| zdotc._Val[1] += Cd(&x[i])._Val[1] * Cd(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cd(&x[i*incx])._Val[0] * Cd(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += Cd(&x[i*incx])._Val[1] * Cd(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex double zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cd(&x[i]) * Cd(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cd(&x[i*incx]) * Cd(&y[i*incy]); | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #endif | |||
| /* -- translated by f2c (version 20000121). | |||
| You must link the resulting object file with the libraries: | |||
| -lf2c -lm (in that order) | |||
| */ | |||
| /* > \brief \b DLARMM */ | |||
| /* Definition: */ | |||
| /* =========== */ | |||
| /* DOUBLE PRECISION FUNCTION DLARMM( ANORM, BNORM, CNORM ) */ | |||
| /* DOUBLE PRECISION ANORM, BNORM, CNORM */ | |||
| /* > \par Purpose: */ | |||
| /* ======= */ | |||
| /* > */ | |||
| /* > \verbatim */ | |||
| /* > */ | |||
| /* > DLARMM returns a factor s in (0, 1] such that the linear updates */ | |||
| /* > */ | |||
| /* > (s * C) - A * (s * B) and (s * C) - (s * A) * B */ | |||
| /* > */ | |||
| /* > cannot overflow, where A, B, and C are matrices of conforming */ | |||
| /* > dimensions. */ | |||
| /* > */ | |||
| /* > This is an auxiliary routine so there is no argument checking. */ | |||
| /* > \endverbatim */ | |||
| /* Arguments: */ | |||
| /* ========= */ | |||
| /* > \param[in] ANORM */ | |||
| /* > \verbatim */ | |||
| /* > ANORM is DOUBLE PRECISION */ | |||
| /* > The infinity norm of A. ANORM >= 0. */ | |||
| /* > The number of rows of the matrix A. M >= 0. */ | |||
| /* > \endverbatim */ | |||
| /* > */ | |||
| /* > \param[in] BNORM */ | |||
| /* > \verbatim */ | |||
| /* > BNORM is DOUBLE PRECISION */ | |||
| /* > The infinity norm of B. BNORM >= 0. */ | |||
| /* > \endverbatim */ | |||
| /* > */ | |||
| /* > \param[in] CNORM */ | |||
| /* > \verbatim */ | |||
| /* > CNORM is DOUBLE PRECISION */ | |||
| /* > The infinity norm of C. CNORM >= 0. */ | |||
| /* > \endverbatim */ | |||
| /* > */ | |||
| /* > */ | |||
| /* ===================================================================== */ | |||
| /* > References: */ | |||
| /* > C. C. Kjelgaard Mikkelsen and L. Karlsson, Blocked Algorithms for */ | |||
| /* > Robust Solution of Triangular Linear Systems. In: International */ | |||
| /* > Conference on Parallel Processing and Applied Mathematics, pages */ | |||
| /* > 68--78. Springer, 2017. */ | |||
| /* > */ | |||
| /* > \ingroup OTHERauxiliary */ | |||
| /* ===================================================================== */ | |||
| doublereal dlarmm_(doublereal *anorm, doublereal *bnorm, doublereal *cnorm) | |||
| { | |||
| /* System generated locals */ | |||
| doublereal ret_val; | |||
| /* Local variables */ | |||
| extern doublereal dlamch_(char *); | |||
| doublereal bignum, smlnum; | |||
| /* Determine machine dependent parameters to control overflow. */ | |||
| smlnum = dlamch_("Safe minimum") / dlamch_("Precision"); | |||
| bignum = 1. / smlnum / 4.; | |||
| /* Compute a scale factor. */ | |||
| ret_val = 1.; | |||
| if (*bnorm <= 1.) { | |||
| if (*anorm * *bnorm > bignum - *cnorm) { | |||
| ret_val = .5; | |||
| } | |||
| } else { | |||
| if (*anorm > (bignum - *cnorm) / *bnorm) { | |||
| ret_val = .5 / *bnorm; | |||
| } | |||
| } | |||
| return ret_val; | |||
| /* ==== End of DLARMM ==== */ | |||
| } /* dlarmm_ */ | |||
| @@ -0,0 +1,99 @@ | |||
| *> \brief \b DLARMM | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * DOUBLE PRECISION FUNCTION DLARMM( ANORM, BNORM, CNORM ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * DOUBLE PRECISION ANORM, BNORM, CNORM | |||
| * .. | |||
| * | |||
| *> \par Purpose: | |||
| * ======= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DLARMM returns a factor s in (0, 1] such that the linear updates | |||
| *> | |||
| *> (s * C) - A * (s * B) and (s * C) - (s * A) * B | |||
| *> | |||
| *> cannot overflow, where A, B, and C are matrices of conforming | |||
| *> dimensions. | |||
| *> | |||
| *> This is an auxiliary routine so there is no argument checking. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========= | |||
| * | |||
| *> \param[in] ANORM | |||
| *> \verbatim | |||
| *> ANORM is DOUBLE PRECISION | |||
| *> The infinity norm of A. ANORM >= 0. | |||
| *> The number of rows of the matrix A. M >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] BNORM | |||
| *> \verbatim | |||
| *> BNORM is DOUBLE PRECISION | |||
| *> The infinity norm of B. BNORM >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] CNORM | |||
| *> \verbatim | |||
| *> CNORM is DOUBLE PRECISION | |||
| *> The infinity norm of C. CNORM >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> | |||
| * ===================================================================== | |||
| *> References: | |||
| *> C. C. Kjelgaard Mikkelsen and L. Karlsson, Blocked Algorithms for | |||
| *> Robust Solution of Triangular Linear Systems. In: International | |||
| *> Conference on Parallel Processing and Applied Mathematics, pages | |||
| *> 68--78. Springer, 2017. | |||
| *> | |||
| *> \ingroup OTHERauxiliary | |||
| * ===================================================================== | |||
| DOUBLE PRECISION FUNCTION DLARMM( ANORM, BNORM, CNORM ) | |||
| IMPLICIT NONE | |||
| * .. Scalar Arguments .. | |||
| DOUBLE PRECISION ANORM, BNORM, CNORM | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE, HALF, FOUR | |||
| PARAMETER ( ONE = 1.0D0, HALF = 0.5D+0, FOUR = 4.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION BIGNUM, SMLNUM | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DLAMCH | |||
| EXTERNAL DLAMCH | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * | |||
| * Determine machine dependent parameters to control overflow. | |||
| * | |||
| SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' ) | |||
| BIGNUM = ( ONE / SMLNUM ) / FOUR | |||
| * | |||
| * Compute a scale factor. | |||
| * | |||
| DLARMM = ONE | |||
| IF( BNORM .LE. ONE ) THEN | |||
| IF( ANORM * BNORM .GT. BIGNUM - CNORM ) THEN | |||
| DLARMM = HALF | |||
| END IF | |||
| ELSE | |||
| IF( ANORM .GT. (BIGNUM - CNORM) / BNORM ) THEN | |||
| DLARMM = HALF / BNORM | |||
| END IF | |||
| END IF | |||
| RETURN | |||
| * | |||
| * ==== End of DLARMM ==== | |||
| * | |||
| END | |||
| @@ -0,0 +1,656 @@ | |||
| *> \brief \b DLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow. | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| * X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER DIAG, NORMIN, TRANS, UPLO | |||
| * INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION A( LDA, * ), CNORM( * ), SCALE( * ), | |||
| * WORK( * ), X( LDX, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DLATRS3 solves one of the triangular systems | |||
| *> | |||
| *> A * X = B * diag(scale) or A**T * X = B * diag(scale) | |||
| *> | |||
| *> with scaling to prevent overflow. Here A is an upper or lower | |||
| *> triangular matrix, A**T denotes the transpose of A. X and B are | |||
| *> n by nrhs matrices and scale is an nrhs element vector of scaling | |||
| *> factors. A scaling factor scale(j) is usually less than or equal | |||
| *> to 1, chosen such that X(:,j) is less than the overflow threshold. | |||
| *> If the matrix A is singular (A(j,j) = 0 for some j), then | |||
| *> a non-trivial solution to A*X = 0 is returned. If the system is | |||
| *> so badly scaled that the solution cannot be represented as | |||
| *> (1/scale(k))*X(:,k), then x(:,k) = 0 and scale(k) is returned. | |||
| *> | |||
| *> This is a BLAS-3 version of LATRS for solving several right | |||
| *> hand sides simultaneously. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the matrix A is upper or lower triangular. | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] TRANS | |||
| *> \verbatim | |||
| *> TRANS is CHARACTER*1 | |||
| *> Specifies the operation applied to A. | |||
| *> = 'N': Solve A * x = s*b (No transpose) | |||
| *> = 'T': Solve A**T* x = s*b (Transpose) | |||
| *> = 'C': Solve A**T* x = s*b (Conjugate transpose = Transpose) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] DIAG | |||
| *> \verbatim | |||
| *> DIAG is CHARACTER*1 | |||
| *> Specifies whether or not the matrix A is unit triangular. | |||
| *> = 'N': Non-unit triangular | |||
| *> = 'U': Unit triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NORMIN | |||
| *> \verbatim | |||
| *> NORMIN is CHARACTER*1 | |||
| *> Specifies whether CNORM has been set or not. | |||
| *> = 'Y': CNORM contains the column norms on entry | |||
| *> = 'N': CNORM is not set on entry. On exit, the norms will | |||
| *> be computed and stored in CNORM. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of columns of X. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION array, dimension (LDA,N) | |||
| *> The triangular matrix A. If UPLO = 'U', the leading n by n | |||
| *> upper triangular part of the array A contains the upper | |||
| *> triangular matrix, and the strictly lower triangular part of | |||
| *> A is not referenced. If UPLO = 'L', the leading n by n lower | |||
| *> triangular part of the array A contains the lower triangular | |||
| *> matrix, and the strictly upper triangular part of A is not | |||
| *> referenced. If DIAG = 'U', the diagonal elements of A are | |||
| *> also not referenced and are assumed to be 1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X | |||
| *> \verbatim | |||
| *> X is DOUBLE PRECISION array, dimension (LDX,NRHS) | |||
| *> On entry, the right hand side B of the triangular system. | |||
| *> On exit, X is overwritten by the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX | |||
| *> \verbatim | |||
| *> LDX is INTEGER | |||
| *> The leading dimension of the array X. LDX >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] SCALE | |||
| *> \verbatim | |||
| *> SCALE is DOUBLE PRECISION array, dimension (NRHS) | |||
| *> The scaling factor s(k) is for the triangular system | |||
| *> A * x(:,k) = s(k)*b(:,k) or A**T* x(:,k) = s(k)*b(:,k). | |||
| *> If SCALE = 0, the matrix A is singular or badly scaled. | |||
| *> If A(j,j) = 0 is encountered, a non-trivial vector x(:,k) | |||
| *> that is an exact or approximate solution to A*x(:,k) = 0 | |||
| *> is returned. If the system so badly scaled that solution | |||
| *> cannot be presented as x(:,k) * 1/s(k), then x(:,k) = 0 | |||
| *> is returned. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] CNORM | |||
| *> \verbatim | |||
| *> CNORM is DOUBLE PRECISION array, dimension (N) | |||
| *> | |||
| *> If NORMIN = 'Y', CNORM is an input argument and CNORM(j) | |||
| *> contains the norm of the off-diagonal part of the j-th column | |||
| *> of A. If TRANS = 'N', CNORM(j) must be greater than or equal | |||
| *> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) | |||
| *> must be greater than or equal to the 1-norm. | |||
| *> | |||
| *> If NORMIN = 'N', CNORM is an output argument and CNORM(j) | |||
| *> returns the 1-norm of the offdiagonal part of the j-th column | |||
| *> of A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal size of | |||
| *> WORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> LWORK is INTEGER | |||
| *> LWORK >= MAX(1, 2*NBA * MAX(NBA, MIN(NRHS, 32)), where | |||
| *> NBA = (N + NB - 1)/NB and NB is the optimal block size. | |||
| *> | |||
| *> If LWORK = -1, then a workspace query is assumed; the routine | |||
| *> only calculates the optimal dimensions of the WORK array, returns | |||
| *> this value as the first entry of the WORK array, and no error | |||
| *> message related to LWORK is issued by XERBLA. | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \ingroup doubleOTHERauxiliary | |||
| *> \par Further Details: | |||
| * ===================== | |||
| * \verbatim | |||
| * The algorithm follows the structure of a block triangular solve. | |||
| * The diagonal block is solved with a call to the robust the triangular | |||
| * solver LATRS for every right-hand side RHS = 1, ..., NRHS | |||
| * op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ), | |||
| * where op( A ) = A or op( A ) = A**T. | |||
| * The linear block updates operate on block columns of X, | |||
| * B( I, K ) - op(A( I, J )) * X( J, K ) | |||
| * and use GEMM. To avoid overflow in the linear block update, the worst case | |||
| * growth is estimated. For every RHS, a scale factor s <= 1.0 is computed | |||
| * such that | |||
| * || s * B( I, RHS )||_oo | |||
| * + || op(A( I, J )) ||_oo * || s * X( J, RHS ) ||_oo <= Overflow threshold | |||
| * | |||
| * Once all columns of a block column have been rescaled (BLAS-1), the linear | |||
| * update is executed with GEMM without overflow. | |||
| * | |||
| * To limit rescaling, local scale factors track the scaling of column segments. | |||
| * There is one local scale factor s( I, RHS ) per block row I = 1, ..., NBA | |||
| * per right-hand side column RHS = 1, ..., NRHS. The global scale factor | |||
| * SCALE( RHS ) is chosen as the smallest local scale factor s( I, RHS ) | |||
| * I = 1, ..., NBA. | |||
| * A triangular solve op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ) | |||
| * updates the local scale factor s( J, RHS ) := s( J, RHS ) * SCALOC. The | |||
| * linear update of potentially inconsistently scaled vector segments | |||
| * s( I, RHS ) * b( I, RHS ) - op(A( I, J )) * ( s( J, RHS )* x( J, RHS ) ) | |||
| * computes a consistent scaling SCAMIN = MIN( s(I, RHS ), s(J, RHS) ) and, | |||
| * if necessary, rescales the blocks prior to calling GEMM. | |||
| * | |||
| * \endverbatim | |||
| * ===================================================================== | |||
| * References: | |||
| * C. C. Kjelgaard Mikkelsen, A. B. Schwarz and L. Karlsson (2019). | |||
| * Parallel robust solution of triangular linear systems. Concurrency | |||
| * and Computation: Practice and Experience, 31(19), e5064. | |||
| * | |||
| * Contributor: | |||
| * Angelika Schwarz, Umea University, Sweden. | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| IMPLICIT NONE | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER DIAG, TRANS, NORMIN, UPLO | |||
| INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION A( LDA, * ), CNORM( * ), X( LDX, * ), | |||
| $ SCALE( * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) | |||
| INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN | |||
| PARAMETER ( NRHSMIN = 2, NBRHS = 32 ) | |||
| PARAMETER ( NBMIN = 8, NBMAX = 64 ) | |||
| * .. | |||
| * .. Local Arrays .. | |||
| DOUBLE PRECISION W( NBMAX ), XNRM( NBRHS ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER | |||
| INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J, | |||
| $ JFIRST, JINC, JLAST, J1, J2, K, KK, K1, K2, | |||
| $ LANRM, LDS, LSCALE, NB, NBA, NBX, RHS | |||
| DOUBLE PRECISION ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC, | |||
| $ SCAMIN, SMLNUM, TMAX | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| DOUBLE PRECISION DLAMCH, DLANGE, DLARMM | |||
| EXTERNAL DLAMCH, DLANGE, DLARMM, ILAENV, LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLATRS, DSCAL, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, MIN | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| NOTRAN = LSAME( TRANS, 'N' ) | |||
| NOUNIT = LSAME( DIAG, 'N' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| * | |||
| * Partition A and X into blocks | |||
| * | |||
| NB = MAX( 8, ILAENV( 1, 'DLATRS', '', N, N, -1, -1 ) ) | |||
| NB = MIN( NBMAX, NB ) | |||
| NBA = MAX( 1, (N + NB - 1) / NB ) | |||
| NBX = MAX( 1, (NRHS + NBRHS - 1) / NBRHS ) | |||
| * | |||
| * Compute the workspace | |||
| * | |||
| * The workspace comprises two parts. | |||
| * The first part stores the local scale factors. Each simultaneously | |||
| * computed right-hand side requires one local scale factor per block | |||
| * row. WORK( I+KK*LDS ) is the scale factor of the vector | |||
| * segment associated with the I-th block row and the KK-th vector | |||
| * in the block column. | |||
| LSCALE = NBA * MAX( NBA, MIN( NRHS, NBRHS ) ) | |||
| LDS = NBA | |||
| * The second part stores upper bounds of the triangular A. There are | |||
| * a total of NBA x NBA blocks, of which only the upper triangular | |||
| * part or the lower triangular part is referenced. The upper bound of | |||
| * the block A( I, J ) is stored as WORK( AWRK + I + J * NBA ). | |||
| LANRM = NBA * NBA | |||
| AWRK = LSCALE | |||
| WORK( 1 ) = LSCALE + LANRM | |||
| * | |||
| * Test the input parameters | |||
| * | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. | |||
| $ LSAME( TRANS, 'C' ) ) THEN | |||
| INFO = -2 | |||
| ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN | |||
| INFO = -3 | |||
| ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT. | |||
| $ LSAME( NORMIN, 'N' ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LDX.LT.MAX( 1, N ) ) THEN | |||
| INFO = -10 | |||
| ELSE IF( .NOT.LQUERY .AND. LWORK.LT.WORK( 1 ) ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DLATRS3', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize scaling factors | |||
| * | |||
| DO KK = 1, NRHS | |||
| SCALE( KK ) = ONE | |||
| END DO | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( MIN( N, NRHS ).EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Determine machine dependent constant to control overflow. | |||
| * | |||
| BIGNUM = DLAMCH( 'Overflow' ) | |||
| SMLNUM = DLAMCH( 'Safe Minimum' ) | |||
| * | |||
| * Use unblocked code for small problems | |||
| * | |||
| IF( NRHS.LT.NRHSMIN ) THEN | |||
| CALL DLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X( 1, 1), | |||
| $ SCALE( 1 ), CNORM, INFO ) | |||
| DO K = 2, NRHS | |||
| CALL DLATRS( UPLO, TRANS, DIAG, 'Y', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute norms of blocks of A excluding diagonal blocks and find | |||
| * the block with the largest norm TMAX. | |||
| * | |||
| TMAX = ZERO | |||
| DO J = 1, NBA | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| IF ( UPPER ) THEN | |||
| IFIRST = 1 | |||
| ILAST = J - 1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| END IF | |||
| DO I = IFIRST, ILAST | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Compute upper bound of A( I1:I2-1, J1:J2-1 ). | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| ANRM = DLANGE( 'I', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + I+(J-1)*NBA ) = ANRM | |||
| ELSE | |||
| ANRM = DLANGE( '1', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + J+(I-1)*NBA ) = ANRM | |||
| END IF | |||
| TMAX = MAX( TMAX, ANRM ) | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( .NOT. TMAX.LE.DLAMCH('Overflow') ) THEN | |||
| * | |||
| * Some matrix entries have huge absolute value. At least one upper | |||
| * bound norm( A(I1:I2-1, J1:J2-1), 'I') is not a valid floating-point | |||
| * number, either due to overflow in LANGE or due to Inf in A. | |||
| * Fall back to LATRS. Set normin = 'N' for every right-hand side to | |||
| * force computation of TSCAL in LATRS to avoid the likely overflow | |||
| * in the computation of the column norms CNORM. | |||
| * | |||
| DO K = 1, NRHS | |||
| CALL DLATRS( UPLO, TRANS, DIAG, 'N', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Every right-hand side requires workspace to store NBA local scale | |||
| * factors. To save workspace, X is computed successively in block columns | |||
| * of width NBRHS, requiring a total of NBA x NBRHS space. If sufficient | |||
| * workspace is available, larger values of NBRHS or NBRHS = NRHS are viable. | |||
| DO K = 1, NBX | |||
| * Loop over block columns (index = K) of X and, for column-wise scalings, | |||
| * over individual columns (index = KK). | |||
| * K1: column index of the first column in X( J, K ) | |||
| * K2: column index of the first column in X( J, K+1 ) | |||
| * so the K2 - K1 is the column count of the block X( J, K ) | |||
| K1 = (K-1)*NBRHS + 1 | |||
| K2 = MIN( K*NBRHS, NRHS ) + 1 | |||
| * | |||
| * Initialize local scaling factors of current block column X( J, K ) | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| DO I = 1, NBA | |||
| WORK( I+KK*LDS ) = ONE | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * Solve A * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| ELSE | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Solve A**T * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| ELSE | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| END IF | |||
| END IF | |||
| * | |||
| DO J = JFIRST, JLAST, JINC | |||
| * J1: row index of the first row in A( J, J ) | |||
| * J2: row index of the first row in A( J+1, J+1 ) | |||
| * so that J2 - J1 is the row count of the block A( J, J ) | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| * | |||
| * Solve op(A( J, J )) * X( J, RHS ) = SCALOC * B( J, RHS ) | |||
| * for all right-hand sides in the current block column, | |||
| * one RHS at a time. | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( KK.EQ.1 ) THEN | |||
| CALL DLATRS( UPLO, TRANS, DIAG, 'N', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| ELSE | |||
| CALL DLATRS( UPLO, TRANS, DIAG, 'Y', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| END IF | |||
| * Find largest absolute value entry in the vector segment | |||
| * X( J1:J2-1, RHS ) as an upper bound for the worst case | |||
| * growth in the linear updates. | |||
| XNRM( KK ) = DLANGE( 'I', J2-J1, 1, X( J1, RHS ), | |||
| $ LDX, W ) | |||
| * | |||
| IF( SCALOC .EQ. ZERO ) THEN | |||
| * LATRS found that A is singular through A(j,j) = 0. | |||
| * Reset the computation x(1:n) = 0, x(j) = 1, SCALE = 0 | |||
| * and compute A*x = 0 (or A**T*x = 0). Note that | |||
| * X(J1:J2-1, KK) is set by LATRS. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, J1-1 | |||
| X( II, KK ) = ZERO | |||
| END DO | |||
| DO II = J2, N | |||
| X( II, KK ) = ZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| ELSE IF( SCALOC * WORK( J+KK*LDS ) .EQ. ZERO ) THEN | |||
| * LATRS computed a valid scale factor, but combined with | |||
| * the current scaling the solution does not have a | |||
| * scale factor > 0. | |||
| * | |||
| * Set WORK( J+KK*LDS ) to smallest valid scale | |||
| * factor and increase SCALOC accordingly. | |||
| SCAL = WORK( J+KK*LDS ) / SMLNUM | |||
| SCALOC = SCALOC * SCAL | |||
| WORK( J+KK*LDS ) = SMLNUM | |||
| * If LATRS overestimated the growth, x may be | |||
| * rescaled to preserve a valid combined scale | |||
| * factor WORK( J, KK ) > 0. | |||
| RSCAL = ONE / SCALOC | |||
| IF( XNRM( KK ) * RSCAL .LE. BIGNUM ) THEN | |||
| XNRM( KK ) = XNRM( KK ) * RSCAL | |||
| CALL DSCAL( J2-J1, RSCAL, X( J1, RHS ), 1 ) | |||
| SCALOC = ONE | |||
| ELSE | |||
| * The system op(A) * x = b is badly scaled and its | |||
| * solution cannot be represented as (1/scale) * x. | |||
| * Set x to zero. This approach deviates from LATRS | |||
| * where a completely meaningless non-zero vector | |||
| * is returned that is not a solution to op(A) * x = b. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, N | |||
| X( II, KK ) = ZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| END IF | |||
| END IF | |||
| SCALOC = SCALOC * WORK( J+KK*LDS ) | |||
| WORK( J+KK*LDS ) = SCALOC | |||
| END DO | |||
| * | |||
| * Linear block updates | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| IF( UPPER ) THEN | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| END IF | |||
| ELSE | |||
| IF( UPPER ) THEN | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| ELSE | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| END IF | |||
| END IF | |||
| * | |||
| DO I = IFIRST, ILAST, IINC | |||
| * I1: row index of the first column in X( I, K ) | |||
| * I2: row index of the first column in X( I+1, K ) | |||
| * so the I2 - I1 is the row count of the block X( I, K ) | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Prepare the linear update to be executed with GEMM. | |||
| * For each column, compute a consistent scaling, a | |||
| * scaling factor to survive the linear update, and | |||
| * rescale the column segments, if necesssary. Then | |||
| * the linear update is safely executed. | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| * Compute consistent scaling | |||
| SCAMIN = MIN( WORK( I + KK*LDS), WORK( J + KK*LDS ) ) | |||
| * | |||
| * Compute scaling factor to survive the linear update | |||
| * simulating consistent scaling. | |||
| * | |||
| BNRM = DLANGE( 'I', I2-I1, 1, X( I1, RHS ), LDX, W ) | |||
| BNRM = BNRM*( SCAMIN / WORK( I+KK*LDS ) ) | |||
| XNRM( KK ) = XNRM( KK )*(SCAMIN / WORK( J+KK*LDS )) | |||
| ANRM = WORK( AWRK + I+(J-1)*NBA ) | |||
| SCALOC = DLARMM( ANRM, XNRM( KK ), BNRM ) | |||
| * | |||
| * Simultaneously apply the robust update factor and the | |||
| * consistency scaling factor to B( I, KK ) and B( J, KK ). | |||
| * | |||
| SCAL = ( SCAMIN / WORK( I+KK*LDS) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL DSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| WORK( I+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| * | |||
| SCAL = ( SCAMIN / WORK( J+KK*LDS ) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL DSCAL( J2-J1, SCAL, X( J1, RHS ), 1 ) | |||
| WORK( J+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J ) * X( J, K ) | |||
| * | |||
| CALL DGEMM( 'N', 'N', I2-I1, K2-K1, J2-J1, -ONE, | |||
| $ A( I1, J1 ), LDA, X( J1, K1 ), LDX, | |||
| $ ONE, X( I1, K1 ), LDX ) | |||
| ELSE | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( J, I )**T * X( J, K ) | |||
| * | |||
| CALL DGEMM( 'T', 'N', I2-I1, K2-K1, J2-J1, -ONE, | |||
| $ A( J1, I1 ), LDA, X( J1, K1 ), LDX, | |||
| $ ONE, X( I1, K1 ), LDX ) | |||
| END IF | |||
| END DO | |||
| END DO | |||
| * | |||
| * Reduce local scaling factors | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| DO I = 1, NBA | |||
| SCALE( RHS ) = MIN( SCALE( RHS ), WORK( I+KK*LDS ) ) | |||
| END DO | |||
| END DO | |||
| * | |||
| * Realize consistent scaling | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( SCALE( RHS ).NE.ONE .AND. SCALE( RHS ).NE. ZERO ) THEN | |||
| DO I = 1, NBA | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| SCAL = SCALE( RHS ) / WORK( I+KK*LDS ) | |||
| IF( SCAL.NE.ONE ) | |||
| $ CALL DSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| END DO | |||
| END IF | |||
| END DO | |||
| END DO | |||
| RETURN | |||
| * | |||
| * End of DLATRS3 | |||
| * | |||
| END | |||
| @@ -469,6 +469,15 @@ | |||
| ELSE | |||
| NB = 64 | |||
| END IF | |||
| ELSE IF( C3.EQ.'SYL' ) THEN | |||
| * The upper bound is to prevent overly aggressive scaling. | |||
| IF( SNAME ) THEN | |||
| NB = MIN( MAX( 48, INT( ( MIN( N1, N2 ) * 16 ) / 100) ), | |||
| $ 240 ) | |||
| ELSE | |||
| NB = MIN( MAX( 24, INT( ( MIN( N1, N2 ) * 8 ) / 100) ), | |||
| $ 80 ) | |||
| END IF | |||
| END IF | |||
| ELSE IF( C2.EQ.'LA' ) THEN | |||
| IF( C3.EQ.'UUM' ) THEN | |||
| @@ -477,6 +486,12 @@ | |||
| ELSE | |||
| NB = 64 | |||
| END IF | |||
| ELSE IF( C3.EQ.'TRS' ) THEN | |||
| IF( SNAME ) THEN | |||
| NB = 32 | |||
| ELSE | |||
| NB = 32 | |||
| END IF | |||
| END IF | |||
| ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN | |||
| IF( C3.EQ.'EBZ' ) THEN | |||
| @@ -0,0 +1,605 @@ | |||
| #include <math.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <complex.h> | |||
| #ifdef complex | |||
| #undef complex | |||
| #endif | |||
| #ifdef I | |||
| #undef I | |||
| #endif | |||
| #if defined(_WIN64) | |||
| typedef long long BLASLONG; | |||
| typedef unsigned long long BLASULONG; | |||
| #else | |||
| typedef long BLASLONG; | |||
| typedef unsigned long BLASULONG; | |||
| #endif | |||
| #ifdef LAPACK_ILP64 | |||
| typedef BLASLONG blasint; | |||
| #if defined(_WIN64) | |||
| #define blasabs(x) llabs(x) | |||
| #else | |||
| #define blasabs(x) labs(x) | |||
| #endif | |||
| #else | |||
| typedef int blasint; | |||
| #define blasabs(x) abs(x) | |||
| #endif | |||
| typedef blasint integer; | |||
| typedef unsigned int uinteger; | |||
| typedef char *address; | |||
| typedef short int shortint; | |||
| typedef float real; | |||
| typedef double doublereal; | |||
| typedef struct { real r, i; } complex; | |||
| typedef struct { doublereal r, i; } doublecomplex; | |||
| #ifdef _MSC_VER | |||
| static inline _Fcomplex Cf(complex *z) {_Fcomplex zz={z->r , z->i}; return zz;} | |||
| static inline _Dcomplex Cd(doublecomplex *z) {_Dcomplex zz={z->r , z->i};return zz;} | |||
| static inline _Fcomplex * _pCf(complex *z) {return (_Fcomplex*)z;} | |||
| static inline _Dcomplex * _pCd(doublecomplex *z) {return (_Dcomplex*)z;} | |||
| #else | |||
| static inline _Complex float Cf(complex *z) {return z->r + z->i*_Complex_I;} | |||
| static inline _Complex double Cd(doublecomplex *z) {return z->r + z->i*_Complex_I;} | |||
| static inline _Complex float * _pCf(complex *z) {return (_Complex float*)z;} | |||
| static inline _Complex double * _pCd(doublecomplex *z) {return (_Complex double*)z;} | |||
| #endif | |||
| #define pCf(z) (*_pCf(z)) | |||
| #define pCd(z) (*_pCd(z)) | |||
| typedef int logical; | |||
| typedef short int shortlogical; | |||
| typedef char logical1; | |||
| typedef char integer1; | |||
| #define TRUE_ (1) | |||
| #define FALSE_ (0) | |||
| /* Extern is for use with -E */ | |||
| #ifndef Extern | |||
| #define Extern extern | |||
| #endif | |||
| /* I/O stuff */ | |||
| typedef int flag; | |||
| typedef int ftnlen; | |||
| typedef int ftnint; | |||
| /*external read, write*/ | |||
| typedef struct | |||
| { flag cierr; | |||
| ftnint ciunit; | |||
| flag ciend; | |||
| char *cifmt; | |||
| ftnint cirec; | |||
| } cilist; | |||
| /*internal read, write*/ | |||
| typedef struct | |||
| { flag icierr; | |||
| char *iciunit; | |||
| flag iciend; | |||
| char *icifmt; | |||
| ftnint icirlen; | |||
| ftnint icirnum; | |||
| } icilist; | |||
| /*open*/ | |||
| typedef struct | |||
| { flag oerr; | |||
| ftnint ounit; | |||
| char *ofnm; | |||
| ftnlen ofnmlen; | |||
| char *osta; | |||
| char *oacc; | |||
| char *ofm; | |||
| ftnint orl; | |||
| char *oblnk; | |||
| } olist; | |||
| /*close*/ | |||
| typedef struct | |||
| { flag cerr; | |||
| ftnint cunit; | |||
| char *csta; | |||
| } cllist; | |||
| /*rewind, backspace, endfile*/ | |||
| typedef struct | |||
| { flag aerr; | |||
| ftnint aunit; | |||
| } alist; | |||
| /* inquire */ | |||
| typedef struct | |||
| { flag inerr; | |||
| ftnint inunit; | |||
| char *infile; | |||
| ftnlen infilen; | |||
| ftnint *inex; /*parameters in standard's order*/ | |||
| ftnint *inopen; | |||
| ftnint *innum; | |||
| ftnint *innamed; | |||
| char *inname; | |||
| ftnlen innamlen; | |||
| char *inacc; | |||
| ftnlen inacclen; | |||
| char *inseq; | |||
| ftnlen inseqlen; | |||
| char *indir; | |||
| ftnlen indirlen; | |||
| char *infmt; | |||
| ftnlen infmtlen; | |||
| char *inform; | |||
| ftnint informlen; | |||
| char *inunf; | |||
| ftnlen inunflen; | |||
| ftnint *inrecl; | |||
| ftnint *innrec; | |||
| char *inblank; | |||
| ftnlen inblanklen; | |||
| } inlist; | |||
| #define VOID void | |||
| union Multitype { /* for multiple entry points */ | |||
| integer1 g; | |||
| shortint h; | |||
| integer i; | |||
| /* longint j; */ | |||
| real r; | |||
| doublereal d; | |||
| complex c; | |||
| doublecomplex z; | |||
| }; | |||
| typedef union Multitype Multitype; | |||
| struct Vardesc { /* for Namelist */ | |||
| char *name; | |||
| char *addr; | |||
| ftnlen *dims; | |||
| int type; | |||
| }; | |||
| typedef struct Vardesc Vardesc; | |||
| struct Namelist { | |||
| char *name; | |||
| Vardesc **vars; | |||
| int nvars; | |||
| }; | |||
| typedef struct Namelist Namelist; | |||
| #define abs(x) ((x) >= 0 ? (x) : -(x)) | |||
| #define dabs(x) (fabs(x)) | |||
| #define f2cmin(a,b) ((a) <= (b) ? (a) : (b)) | |||
| #define f2cmax(a,b) ((a) >= (b) ? (a) : (b)) | |||
| #define dmin(a,b) (f2cmin(a,b)) | |||
| #define dmax(a,b) (f2cmax(a,b)) | |||
| #define bit_test(a,b) ((a) >> (b) & 1) | |||
| #define bit_clear(a,b) ((a) & ~((uinteger)1 << (b))) | |||
| #define bit_set(a,b) ((a) | ((uinteger)1 << (b))) | |||
| #define abort_() { sig_die("Fortran abort routine called", 1); } | |||
| #define c_abs(z) (cabsf(Cf(z))) | |||
| #define c_cos(R,Z) { pCf(R)=ccos(Cf(Z)); } | |||
| #ifdef _MSC_VER | |||
| #define c_div(c, a, b) {Cf(c)._Val[0] = (Cf(a)._Val[0]/Cf(b)._Val[0]); Cf(c)._Val[1]=(Cf(a)._Val[1]/Cf(b)._Val[1]);} | |||
| #define z_div(c, a, b) {Cd(c)._Val[0] = (Cd(a)._Val[0]/Cd(b)._Val[0]); Cd(c)._Val[1]=(Cd(a)._Val[1]/Cd(b)._Val[1]);} | |||
| #else | |||
| #define c_div(c, a, b) {pCf(c) = Cf(a)/Cf(b);} | |||
| #define z_div(c, a, b) {pCd(c) = Cd(a)/Cd(b);} | |||
| #endif | |||
| #define c_exp(R, Z) {pCf(R) = cexpf(Cf(Z));} | |||
| #define c_log(R, Z) {pCf(R) = clogf(Cf(Z));} | |||
| #define c_sin(R, Z) {pCf(R) = csinf(Cf(Z));} | |||
| //#define c_sqrt(R, Z) {*(R) = csqrtf(Cf(Z));} | |||
| #define c_sqrt(R, Z) {pCf(R) = csqrtf(Cf(Z));} | |||
| #define d_abs(x) (fabs(*(x))) | |||
| #define d_acos(x) (acos(*(x))) | |||
| #define d_asin(x) (asin(*(x))) | |||
| #define d_atan(x) (atan(*(x))) | |||
| #define d_atn2(x, y) (atan2(*(x),*(y))) | |||
| #define d_cnjg(R, Z) { pCd(R) = conj(Cd(Z)); } | |||
| #define r_cnjg(R, Z) { pCf(R) = conjf(Cf(Z)); } | |||
| #define d_cos(x) (cos(*(x))) | |||
| #define d_cosh(x) (cosh(*(x))) | |||
| #define d_dim(__a, __b) ( *(__a) > *(__b) ? *(__a) - *(__b) : 0.0 ) | |||
| #define d_exp(x) (exp(*(x))) | |||
| #define d_imag(z) (cimag(Cd(z))) | |||
| #define r_imag(z) (cimagf(Cf(z))) | |||
| #define d_int(__x) (*(__x)>0 ? floor(*(__x)) : -floor(- *(__x))) | |||
| #define r_int(__x) (*(__x)>0 ? floor(*(__x)) : -floor(- *(__x))) | |||
| #define d_lg10(x) ( 0.43429448190325182765 * log(*(x)) ) | |||
| #define r_lg10(x) ( 0.43429448190325182765 * log(*(x)) ) | |||
| #define d_log(x) (log(*(x))) | |||
| #define d_mod(x, y) (fmod(*(x), *(y))) | |||
| #define u_nint(__x) ((__x)>=0 ? floor((__x) + .5) : -floor(.5 - (__x))) | |||
| #define d_nint(x) u_nint(*(x)) | |||
| #define u_sign(__a,__b) ((__b) >= 0 ? ((__a) >= 0 ? (__a) : -(__a)) : -((__a) >= 0 ? (__a) : -(__a))) | |||
| #define d_sign(a,b) u_sign(*(a),*(b)) | |||
| #define r_sign(a,b) u_sign(*(a),*(b)) | |||
| #define d_sin(x) (sin(*(x))) | |||
| #define d_sinh(x) (sinh(*(x))) | |||
| #define d_sqrt(x) (sqrt(*(x))) | |||
| #define d_tan(x) (tan(*(x))) | |||
| #define d_tanh(x) (tanh(*(x))) | |||
| #define i_abs(x) abs(*(x)) | |||
| #define i_dnnt(x) ((integer)u_nint(*(x))) | |||
| #define i_len(s, n) (n) | |||
| #define i_nint(x) ((integer)u_nint(*(x))) | |||
| #define i_sign(a,b) ((integer)u_sign((integer)*(a),(integer)*(b))) | |||
| #define pow_dd(ap, bp) ( pow(*(ap), *(bp))) | |||
| #define pow_si(B,E) spow_ui(*(B),*(E)) | |||
| #define pow_ri(B,E) spow_ui(*(B),*(E)) | |||
| #define pow_di(B,E) dpow_ui(*(B),*(E)) | |||
| #define pow_zi(p, a, b) {pCd(p) = zpow_ui(Cd(a), *(b));} | |||
| #define pow_ci(p, a, b) {pCf(p) = cpow_ui(Cf(a), *(b));} | |||
| #define pow_zz(R,A,B) {pCd(R) = cpow(Cd(A),*(B));} | |||
| #define s_cat(lpp, rpp, rnp, np, llp) { ftnlen i, nc, ll; char *f__rp, *lp; ll = (llp); lp = (lpp); for(i=0; i < (int)*(np); ++i) { nc = ll; if((rnp)[i] < nc) nc = (rnp)[i]; ll -= nc; f__rp = (rpp)[i]; while(--nc >= 0) *lp++ = *(f__rp)++; } while(--ll >= 0) *lp++ = ' '; } | |||
| #define s_cmp(a,b,c,d) ((integer)strncmp((a),(b),f2cmin((c),(d)))) | |||
| #define s_copy(A,B,C,D) { int __i,__m; for (__i=0, __m=f2cmin((C),(D)); __i<__m && (B)[__i] != 0; ++__i) (A)[__i] = (B)[__i]; } | |||
| #define sig_die(s, kill) { exit(1); } | |||
| #define s_stop(s, n) {exit(0);} | |||
| static char junk[] = "\n@(#)LIBF77 VERSION 19990503\n"; | |||
| #define z_abs(z) (cabs(Cd(z))) | |||
| #define z_exp(R, Z) {pCd(R) = cexp(Cd(Z));} | |||
| #define z_sqrt(R, Z) {pCd(R) = csqrt(Cd(Z));} | |||
| #define myexit_() break; | |||
| #define mycycle_() continue; | |||
| #define myceiling_(w) {ceil(w)} | |||
| #define myhuge_(w) {HUGE_VAL} | |||
| //#define mymaxloc_(w,s,e,n) {if (sizeof(*(w)) == sizeof(double)) dmaxloc_((w),*(s),*(e),n); else dmaxloc_((w),*(s),*(e),n);} | |||
| #define mymaxloc_(w,s,e,n) dmaxloc_(w,*(s),*(e),n) | |||
| #define myexp_(w) my_expfunc(w) | |||
| static int my_expfunc(float *x) {int e; (void)frexpf(*x,&e); return e;} | |||
| /* procedure parameter types for -A and -C++ */ | |||
| #define F2C_proc_par_types 1 | |||
| #ifdef __cplusplus | |||
| typedef logical (*L_fp)(...); | |||
| #else | |||
| typedef logical (*L_fp)(); | |||
| #endif | |||
| static float spow_ui(float x, integer n) { | |||
| float pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| static double dpow_ui(double x, integer n) { | |||
| double pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| #ifdef _MSC_VER | |||
| static _Fcomplex cpow_ui(complex x, integer n) { | |||
| complex pow={1.0,0.0}; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x.r = 1/x.r, x.i=1/x.i; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow.r *= x.r, pow.i *= x.i; | |||
| if(u >>= 1) x.r *= x.r, x.i *= x.i; | |||
| else break; | |||
| } | |||
| } | |||
| _Fcomplex p={pow.r, pow.i}; | |||
| return p; | |||
| } | |||
| #else | |||
| static _Complex float cpow_ui(_Complex float x, integer n) { | |||
| _Complex float pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| #endif | |||
| #ifdef _MSC_VER | |||
| static _Dcomplex zpow_ui(_Dcomplex x, integer n) { | |||
| _Dcomplex pow={1.0,0.0}; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x._Val[0] = 1/x._Val[0], x._Val[1] =1/x._Val[1]; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow._Val[0] *= x._Val[0], pow._Val[1] *= x._Val[1]; | |||
| if(u >>= 1) x._Val[0] *= x._Val[0], x._Val[1] *= x._Val[1]; | |||
| else break; | |||
| } | |||
| } | |||
| _Dcomplex p = {pow._Val[0], pow._Val[1]}; | |||
| return p; | |||
| } | |||
| #else | |||
| static _Complex double zpow_ui(_Complex double x, integer n) { | |||
| _Complex double pow=1.0; unsigned long int u; | |||
| if(n != 0) { | |||
| if(n < 0) n = -n, x = 1/x; | |||
| for(u = n; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| #endif | |||
| static integer pow_ii(integer x, integer n) { | |||
| integer pow; unsigned long int u; | |||
| if (n <= 0) { | |||
| if (n == 0 || x == 1) pow = 1; | |||
| else if (x != -1) pow = x == 0 ? 1/x : 0; | |||
| else n = -n; | |||
| } | |||
| if ((n > 0) || !(n == 0 || x == 1 || x != -1)) { | |||
| u = n; | |||
| for(pow = 1; ; ) { | |||
| if(u & 01) pow *= x; | |||
| if(u >>= 1) x *= x; | |||
| else break; | |||
| } | |||
| } | |||
| return pow; | |||
| } | |||
| static integer dmaxloc_(double *w, integer s, integer e, integer *n) | |||
| { | |||
| double m; integer i, mi; | |||
| for(m=w[s-1], mi=s, i=s+1; i<=e; i++) | |||
| if (w[i-1]>m) mi=i ,m=w[i-1]; | |||
| return mi-s+1; | |||
| } | |||
| static integer smaxloc_(float *w, integer s, integer e, integer *n) | |||
| { | |||
| float m; integer i, mi; | |||
| for(m=w[s-1], mi=s, i=s+1; i<=e; i++) | |||
| if (w[i-1]>m) mi=i ,m=w[i-1]; | |||
| return mi-s+1; | |||
| } | |||
| static inline void cdotc_(complex *z, integer *n_, complex *x, integer *incx_, complex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Fcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conjf(Cf(&x[i]))._Val[0] * Cf(&y[i])._Val[0]; | |||
| zdotc._Val[1] += conjf(Cf(&x[i]))._Val[1] * Cf(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conjf(Cf(&x[i*incx]))._Val[0] * Cf(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += conjf(Cf(&x[i*incx]))._Val[1] * Cf(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex float zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conjf(Cf(&x[i])) * Cf(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conjf(Cf(&x[i*incx])) * Cf(&y[i*incy]); | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #endif | |||
| static inline void zdotc_(doublecomplex *z, integer *n_, doublecomplex *x, integer *incx_, doublecomplex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Dcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conj(Cd(&x[i]))._Val[0] * Cd(&y[i])._Val[0]; | |||
| zdotc._Val[1] += conj(Cd(&x[i]))._Val[1] * Cd(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += conj(Cd(&x[i*incx]))._Val[0] * Cd(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += conj(Cd(&x[i*incx]))._Val[1] * Cd(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex double zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conj(Cd(&x[i])) * Cd(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += conj(Cd(&x[i*incx])) * Cd(&y[i*incy]); | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #endif | |||
| static inline void cdotu_(complex *z, integer *n_, complex *x, integer *incx_, complex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Fcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cf(&x[i])._Val[0] * Cf(&y[i])._Val[0]; | |||
| zdotc._Val[1] += Cf(&x[i])._Val[1] * Cf(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cf(&x[i*incx])._Val[0] * Cf(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += Cf(&x[i*incx])._Val[1] * Cf(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex float zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cf(&x[i]) * Cf(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cf(&x[i*incx]) * Cf(&y[i*incy]); | |||
| } | |||
| } | |||
| pCf(z) = zdotc; | |||
| } | |||
| #endif | |||
| static inline void zdotu_(doublecomplex *z, integer *n_, doublecomplex *x, integer *incx_, doublecomplex *y, integer *incy_) { | |||
| integer n = *n_, incx = *incx_, incy = *incy_, i; | |||
| #ifdef _MSC_VER | |||
| _Dcomplex zdotc = {0.0, 0.0}; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cd(&x[i])._Val[0] * Cd(&y[i])._Val[0]; | |||
| zdotc._Val[1] += Cd(&x[i])._Val[1] * Cd(&y[i])._Val[1]; | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc._Val[0] += Cd(&x[i*incx])._Val[0] * Cd(&y[i*incy])._Val[0]; | |||
| zdotc._Val[1] += Cd(&x[i*incx])._Val[1] * Cd(&y[i*incy])._Val[1]; | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #else | |||
| _Complex double zdotc = 0.0; | |||
| if (incx == 1 && incy == 1) { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cd(&x[i]) * Cd(&y[i]); | |||
| } | |||
| } else { | |||
| for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */ | |||
| zdotc += Cd(&x[i*incx]) * Cd(&y[i*incy]); | |||
| } | |||
| } | |||
| pCd(z) = zdotc; | |||
| } | |||
| #endif | |||
| /* -- translated by f2c (version 20000121). | |||
| You must link the resulting object file with the libraries: | |||
| -lf2c -lm (in that order) | |||
| */ | |||
| /* > \brief \b SLARMM */ | |||
| /* Definition: */ | |||
| /* =========== */ | |||
| /* REAL FUNCTION SLARMM( ANORM, BNORM, CNORM ) */ | |||
| /* REAL ANORM, BNORM, CNORM */ | |||
| /* > \par Purpose: */ | |||
| /* ======= */ | |||
| /* > */ | |||
| /* > \verbatim */ | |||
| /* > */ | |||
| /* > SLARMM returns a factor s in (0, 1] such that the linear updates */ | |||
| /* > */ | |||
| /* > (s * C) - A * (s * B) and (s * C) - (s * A) * B */ | |||
| /* > */ | |||
| /* > cannot overflow, where A, B, and C are matrices of conforming */ | |||
| /* > dimensions. */ | |||
| /* > */ | |||
| /* > This is an auxiliary routine so there is no argument checking. */ | |||
| /* > \endverbatim */ | |||
| /* Arguments: */ | |||
| /* ========= */ | |||
| /* > \param[in] ANORM */ | |||
| /* > \verbatim */ | |||
| /* > ANORM is REAL */ | |||
| /* > The infinity norm of A. ANORM >= 0. */ | |||
| /* > The number of rows of the matrix A. M >= 0. */ | |||
| /* > \endverbatim */ | |||
| /* > */ | |||
| /* > \param[in] BNORM */ | |||
| /* > \verbatim */ | |||
| /* > BNORM is REAL */ | |||
| /* > The infinity norm of B. BNORM >= 0. */ | |||
| /* > \endverbatim */ | |||
| /* > */ | |||
| /* > \param[in] CNORM */ | |||
| /* > \verbatim */ | |||
| /* > CNORM is REAL */ | |||
| /* > The infinity norm of C. CNORM >= 0. */ | |||
| /* > \endverbatim */ | |||
| /* > */ | |||
| /* > */ | |||
| /* ===================================================================== */ | |||
| /* > References: */ | |||
| /* > C. C. Kjelgaard Mikkelsen and L. Karlsson, Blocked Algorithms for */ | |||
| /* > Robust Solution of Triangular Linear Systems. In: International */ | |||
| /* > Conference on Parallel Processing and Applied Mathematics, pages */ | |||
| /* > 68--78. Springer, 2017. */ | |||
| /* > */ | |||
| /* > \ingroup OTHERauxiliary */ | |||
| /* ===================================================================== */ | |||
| real slarmm_(real *anorm, real *bnorm, real *cnorm) | |||
| { | |||
| /* System generated locals */ | |||
| real ret_val; | |||
| /* Local variables */ | |||
| extern real slamch_(char *); | |||
| real bignum, smlnum; | |||
| /* Determine machine dependent parameters to control overflow. */ | |||
| smlnum = slamch_("Safe minimum") / slamch_("Precision"); | |||
| bignum = 1.f / smlnum / 4.f; | |||
| /* Compute a scale factor. */ | |||
| ret_val = 1.f; | |||
| if (*bnorm <= 1.f) { | |||
| if (*anorm * *bnorm > bignum - *cnorm) { | |||
| ret_val = .5f; | |||
| } | |||
| } else { | |||
| if (*anorm > (bignum - *cnorm) / *bnorm) { | |||
| ret_val = .5f / *bnorm; | |||
| } | |||
| } | |||
| return ret_val; | |||
| /* ==== End of SLARMM ==== */ | |||
| } /* slarmm_ */ | |||
| @@ -0,0 +1,99 @@ | |||
| *> \brief \b SLARMM | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * REAL FUNCTION SLARMM( ANORM, BNORM, CNORM ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * REAL ANORM, BNORM, CNORM | |||
| * .. | |||
| * | |||
| *> \par Purpose: | |||
| * ======= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> SLARMM returns a factor s in (0, 1] such that the linear updates | |||
| *> | |||
| *> (s * C) - A * (s * B) and (s * C) - (s * A) * B | |||
| *> | |||
| *> cannot overflow, where A, B, and C are matrices of conforming | |||
| *> dimensions. | |||
| *> | |||
| *> This is an auxiliary routine so there is no argument checking. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========= | |||
| * | |||
| *> \param[in] ANORM | |||
| *> \verbatim | |||
| *> ANORM is REAL | |||
| *> The infinity norm of A. ANORM >= 0. | |||
| *> The number of rows of the matrix A. M >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] BNORM | |||
| *> \verbatim | |||
| *> BNORM is REAL | |||
| *> The infinity norm of B. BNORM >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] CNORM | |||
| *> \verbatim | |||
| *> CNORM is REAL | |||
| *> The infinity norm of C. CNORM >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> | |||
| * ===================================================================== | |||
| *> References: | |||
| *> C. C. Kjelgaard Mikkelsen and L. Karlsson, Blocked Algorithms for | |||
| *> Robust Solution of Triangular Linear Systems. In: International | |||
| *> Conference on Parallel Processing and Applied Mathematics, pages | |||
| *> 68--78. Springer, 2017. | |||
| *> | |||
| *> \ingroup OTHERauxiliary | |||
| * ===================================================================== | |||
| REAL FUNCTION SLARMM( ANORM, BNORM, CNORM ) | |||
| IMPLICIT NONE | |||
| * .. Scalar Arguments .. | |||
| REAL ANORM, BNORM, CNORM | |||
| * .. Parameters .. | |||
| REAL ONE, HALF, FOUR | |||
| PARAMETER ( ONE = 1.0E0, HALF = 0.5E+0, FOUR = 4.0E+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| REAL BIGNUM, SMLNUM | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SLAMCH | |||
| EXTERNAL SLAMCH | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * | |||
| * Determine machine dependent parameters to control overflow. | |||
| * | |||
| SMLNUM = SLAMCH( 'Safe minimum' ) / SLAMCH( 'Precision' ) | |||
| BIGNUM = ( ONE / SMLNUM ) / FOUR | |||
| * | |||
| * Compute a scale factor. | |||
| * | |||
| SLARMM = ONE | |||
| IF( BNORM .LE. ONE ) THEN | |||
| IF( ANORM * BNORM .GT. BIGNUM - CNORM ) THEN | |||
| SLARMM = HALF | |||
| END IF | |||
| ELSE | |||
| IF( ANORM .GT. (BIGNUM - CNORM) / BNORM ) THEN | |||
| SLARMM = HALF / BNORM | |||
| END IF | |||
| END IF | |||
| RETURN | |||
| * | |||
| * ==== End of SLARMM ==== | |||
| * | |||
| END | |||
| @@ -0,0 +1,656 @@ | |||
| *> \brief \b SLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow. | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE SLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| * X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER DIAG, NORMIN, TRANS, UPLO | |||
| * INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL A( LDA, * ), CNORM( * ), SCALE( * ), | |||
| * WORK( * ), X( LDX, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> SLATRS3 solves one of the triangular systems | |||
| *> | |||
| *> A * X = B * diag(scale) or A**T * X = B * diag(scale) | |||
| *> | |||
| *> with scaling to prevent overflow. Here A is an upper or lower | |||
| *> triangular matrix, A**T denotes the transpose of A. X and B are | |||
| *> n by nrhs matrices and scale is an nrhs element vector of scaling | |||
| *> factors. A scaling factor scale(j) is usually less than or equal | |||
| *> to 1, chosen such that X(:,j) is less than the overflow threshold. | |||
| *> If the matrix A is singular (A(j,j) = 0 for some j), then | |||
| *> a non-trivial solution to A*X = 0 is returned. If the system is | |||
| *> so badly scaled that the solution cannot be represented as | |||
| *> (1/scale(k))*X(:,k), then x(:,k) = 0 and scale(k) is returned. | |||
| *> | |||
| *> This is a BLAS-3 version of LATRS for solving several right | |||
| *> hand sides simultaneously. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the matrix A is upper or lower triangular. | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] TRANS | |||
| *> \verbatim | |||
| *> TRANS is CHARACTER*1 | |||
| *> Specifies the operation applied to A. | |||
| *> = 'N': Solve A * x = s*b (No transpose) | |||
| *> = 'T': Solve A**T* x = s*b (Transpose) | |||
| *> = 'C': Solve A**T* x = s*b (Conjugate transpose = Transpose) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] DIAG | |||
| *> \verbatim | |||
| *> DIAG is CHARACTER*1 | |||
| *> Specifies whether or not the matrix A is unit triangular. | |||
| *> = 'N': Non-unit triangular | |||
| *> = 'U': Unit triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NORMIN | |||
| *> \verbatim | |||
| *> NORMIN is CHARACTER*1 | |||
| *> Specifies whether CNORM has been set or not. | |||
| *> = 'Y': CNORM contains the column norms on entry | |||
| *> = 'N': CNORM is not set on entry. On exit, the norms will | |||
| *> be computed and stored in CNORM. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of columns of X. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is REAL array, dimension (LDA,N) | |||
| *> The triangular matrix A. If UPLO = 'U', the leading n by n | |||
| *> upper triangular part of the array A contains the upper | |||
| *> triangular matrix, and the strictly lower triangular part of | |||
| *> A is not referenced. If UPLO = 'L', the leading n by n lower | |||
| *> triangular part of the array A contains the lower triangular | |||
| *> matrix, and the strictly upper triangular part of A is not | |||
| *> referenced. If DIAG = 'U', the diagonal elements of A are | |||
| *> also not referenced and are assumed to be 1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X | |||
| *> \verbatim | |||
| *> X is REAL array, dimension (LDX,NRHS) | |||
| *> On entry, the right hand side B of the triangular system. | |||
| *> On exit, X is overwritten by the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX | |||
| *> \verbatim | |||
| *> LDX is INTEGER | |||
| *> The leading dimension of the array X. LDX >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] SCALE | |||
| *> \verbatim | |||
| *> SCALE is REAL array, dimension (NRHS) | |||
| *> The scaling factor s(k) is for the triangular system | |||
| *> A * x(:,k) = s(k)*b(:,k) or A**T* x(:,k) = s(k)*b(:,k). | |||
| *> If SCALE = 0, the matrix A is singular or badly scaled. | |||
| *> If A(j,j) = 0 is encountered, a non-trivial vector x(:,k) | |||
| *> that is an exact or approximate solution to A*x(:,k) = 0 | |||
| *> is returned. If the system so badly scaled that solution | |||
| *> cannot be presented as x(:,k) * 1/s(k), then x(:,k) = 0 | |||
| *> is returned. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] CNORM | |||
| *> \verbatim | |||
| *> CNORM is REAL array, dimension (N) | |||
| *> | |||
| *> If NORMIN = 'Y', CNORM is an input argument and CNORM(j) | |||
| *> contains the norm of the off-diagonal part of the j-th column | |||
| *> of A. If TRANS = 'N', CNORM(j) must be greater than or equal | |||
| *> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) | |||
| *> must be greater than or equal to the 1-norm. | |||
| *> | |||
| *> If NORMIN = 'N', CNORM is an output argument and CNORM(j) | |||
| *> returns the 1-norm of the offdiagonal part of the j-th column | |||
| *> of A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is REAL array, dimension (LWORK). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal size of | |||
| *> WORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> LWORK is INTEGER | |||
| *> LWORK >= MAX(1, 2*NBA * MAX(NBA, MIN(NRHS, 32)), where | |||
| *> NBA = (N + NB - 1)/NB and NB is the optimal block size. | |||
| *> | |||
| *> If LWORK = -1, then a workspace query is assumed; the routine | |||
| *> only calculates the optimal dimensions of the WORK array, returns | |||
| *> this value as the first entry of the WORK array, and no error | |||
| *> message related to LWORK is issued by XERBLA. | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \ingroup doubleOTHERauxiliary | |||
| *> \par Further Details: | |||
| * ===================== | |||
| * \verbatim | |||
| * The algorithm follows the structure of a block triangular solve. | |||
| * The diagonal block is solved with a call to the robust the triangular | |||
| * solver LATRS for every right-hand side RHS = 1, ..., NRHS | |||
| * op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ), | |||
| * where op( A ) = A or op( A ) = A**T. | |||
| * The linear block updates operate on block columns of X, | |||
| * B( I, K ) - op(A( I, J )) * X( J, K ) | |||
| * and use GEMM. To avoid overflow in the linear block update, the worst case | |||
| * growth is estimated. For every RHS, a scale factor s <= 1.0 is computed | |||
| * such that | |||
| * || s * B( I, RHS )||_oo | |||
| * + || op(A( I, J )) ||_oo * || s * X( J, RHS ) ||_oo <= Overflow threshold | |||
| * | |||
| * Once all columns of a block column have been rescaled (BLAS-1), the linear | |||
| * update is executed with GEMM without overflow. | |||
| * | |||
| * To limit rescaling, local scale factors track the scaling of column segments. | |||
| * There is one local scale factor s( I, RHS ) per block row I = 1, ..., NBA | |||
| * per right-hand side column RHS = 1, ..., NRHS. The global scale factor | |||
| * SCALE( RHS ) is chosen as the smallest local scale factor s( I, RHS ) | |||
| * I = 1, ..., NBA. | |||
| * A triangular solve op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ) | |||
| * updates the local scale factor s( J, RHS ) := s( J, RHS ) * SCALOC. The | |||
| * linear update of potentially inconsistently scaled vector segments | |||
| * s( I, RHS ) * b( I, RHS ) - op(A( I, J )) * ( s( J, RHS )* x( J, RHS ) ) | |||
| * computes a consistent scaling SCAMIN = MIN( s(I, RHS ), s(J, RHS) ) and, | |||
| * if necessary, rescales the blocks prior to calling GEMM. | |||
| * | |||
| * \endverbatim | |||
| * ===================================================================== | |||
| * References: | |||
| * C. C. Kjelgaard Mikkelsen, A. B. Schwarz and L. Karlsson (2019). | |||
| * Parallel robust solution of triangular linear systems. Concurrency | |||
| * and Computation: Practice and Experience, 31(19), e5064. | |||
| * | |||
| * Contributor: | |||
| * Angelika Schwarz, Umea University, Sweden. | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE SLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| IMPLICIT NONE | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER DIAG, TRANS, NORMIN, UPLO | |||
| INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| REAL A( LDA, * ), CNORM( * ), X( LDX, * ), | |||
| $ SCALE( * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN | |||
| PARAMETER ( NRHSMIN = 2, NBRHS = 32 ) | |||
| PARAMETER ( NBMIN = 8, NBMAX = 64 ) | |||
| * .. | |||
| * .. Local Arrays .. | |||
| REAL W( NBMAX ), XNRM( NBRHS ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER | |||
| INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J, | |||
| $ JFIRST, JINC, JLAST, J1, J2, K, KK, K1, K2, | |||
| $ LANRM, LDS, LSCALE, NB, NBA, NBX, RHS | |||
| REAL ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC, | |||
| $ SCAMIN, SMLNUM, TMAX | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| REAL SLAMCH, SLANGE, SLARMM | |||
| EXTERNAL ILAENV, LSAME, SLAMCH, SLANGE, SLARMM | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL SLATRS, SSCAL, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, MIN | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| NOTRAN = LSAME( TRANS, 'N' ) | |||
| NOUNIT = LSAME( DIAG, 'N' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| * | |||
| * Partition A and X into blocks. | |||
| * | |||
| NB = MAX( 8, ILAENV( 1, 'SLATRS', '', N, N, -1, -1 ) ) | |||
| NB = MIN( NBMAX, NB ) | |||
| NBA = MAX( 1, (N + NB - 1) / NB ) | |||
| NBX = MAX( 1, (NRHS + NBRHS - 1) / NBRHS ) | |||
| * | |||
| * Compute the workspace | |||
| * | |||
| * The workspace comprises two parts. | |||
| * The first part stores the local scale factors. Each simultaneously | |||
| * computed right-hand side requires one local scale factor per block | |||
| * row. WORK( I + KK * LDS ) is the scale factor of the vector | |||
| * segment associated with the I-th block row and the KK-th vector | |||
| * in the block column. | |||
| LSCALE = NBA * MAX( NBA, MIN( NRHS, NBRHS ) ) | |||
| LDS = NBA | |||
| * The second part stores upper bounds of the triangular A. There are | |||
| * a total of NBA x NBA blocks, of which only the upper triangular | |||
| * part or the lower triangular part is referenced. The upper bound of | |||
| * the block A( I, J ) is stored as WORK( AWRK + I + J * NBA ). | |||
| LANRM = NBA * NBA | |||
| AWRK = LSCALE | |||
| WORK( 1 ) = LSCALE + LANRM | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. | |||
| $ LSAME( TRANS, 'C' ) ) THEN | |||
| INFO = -2 | |||
| ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN | |||
| INFO = -3 | |||
| ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT. | |||
| $ LSAME( NORMIN, 'N' ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LDX.LT.MAX( 1, N ) ) THEN | |||
| INFO = -10 | |||
| ELSE IF( .NOT.LQUERY .AND. LWORK.LT.WORK( 1 ) ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'SLATRS3', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize scaling factors | |||
| * | |||
| DO KK = 1, NRHS | |||
| SCALE( KK ) = ONE | |||
| END DO | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( MIN( N, NRHS ).EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Determine machine dependent constant to control overflow. | |||
| * | |||
| BIGNUM = SLAMCH( 'Overflow' ) | |||
| SMLNUM = SLAMCH( 'Safe Minimum' ) | |||
| * | |||
| * Use unblocked code for small problems | |||
| * | |||
| IF( NRHS.LT.NRHSMIN ) THEN | |||
| CALL SLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X( 1, 1), | |||
| $ SCALE( 1 ), CNORM, INFO ) | |||
| DO K = 2, NRHS | |||
| CALL SLATRS( UPLO, TRANS, DIAG, 'Y', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute norms of blocks of A excluding diagonal blocks and find | |||
| * the block with the largest norm TMAX. | |||
| * | |||
| TMAX = ZERO | |||
| DO J = 1, NBA | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| IF ( UPPER ) THEN | |||
| IFIRST = 1 | |||
| ILAST = J - 1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| END IF | |||
| DO I = IFIRST, ILAST | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Compute upper bound of A( I1:I2-1, J1:J2-1 ). | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| ANRM = SLANGE( 'I', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + I+(J-1)*NBA ) = ANRM | |||
| ELSE | |||
| ANRM = SLANGE( '1', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + J+(I-1)*NBA ) = ANRM | |||
| END IF | |||
| TMAX = MAX( TMAX, ANRM ) | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( .NOT. TMAX.LE.SLAMCH('Overflow') ) THEN | |||
| * | |||
| * Some matrix entries have huge absolute value. At least one upper | |||
| * bound norm( A(I1:I2-1, J1:J2-1), 'I') is not a valid floating-point | |||
| * number, either due to overflow in LANGE or due to Inf in A. | |||
| * Fall back to LATRS. Set normin = 'N' for every right-hand side to | |||
| * force computation of TSCAL in LATRS to avoid the likely overflow | |||
| * in the computation of the column norms CNORM. | |||
| * | |||
| DO K = 1, NRHS | |||
| CALL SLATRS( UPLO, TRANS, DIAG, 'N', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Every right-hand side requires workspace to store NBA local scale | |||
| * factors. To save workspace, X is computed successively in block columns | |||
| * of width NBRHS, requiring a total of NBA x NBRHS space. If sufficient | |||
| * workspace is available, larger values of NBRHS or NBRHS = NRHS are viable. | |||
| DO K = 1, NBX | |||
| * Loop over block columns (index = K) of X and, for column-wise scalings, | |||
| * over individual columns (index = KK). | |||
| * K1: column index of the first column in X( J, K ) | |||
| * K2: column index of the first column in X( J, K+1 ) | |||
| * so the K2 - K1 is the column count of the block X( J, K ) | |||
| K1 = (K-1)*NBRHS + 1 | |||
| K2 = MIN( K*NBRHS, NRHS ) + 1 | |||
| * | |||
| * Initialize local scaling factors of current block column X( J, K ) | |||
| * | |||
| DO KK = 1, K2 - K1 | |||
| DO I = 1, NBA | |||
| WORK( I+KK*LDS ) = ONE | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * Solve A * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| ELSE | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Solve A**T * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| ELSE | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| END IF | |||
| END IF | |||
| * | |||
| DO J = JFIRST, JLAST, JINC | |||
| * J1: row index of the first row in A( J, J ) | |||
| * J2: row index of the first row in A( J+1, J+1 ) | |||
| * so that J2 - J1 is the row count of the block A( J, J ) | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| * | |||
| * Solve op(A( J, J )) * X( J, RHS ) = SCALOC * B( J, RHS ) | |||
| * for all right-hand sides in the current block column, | |||
| * one RHS at a time. | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( KK.EQ.1 ) THEN | |||
| CALL SLATRS( UPLO, TRANS, DIAG, 'N', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| ELSE | |||
| CALL SLATRS( UPLO, TRANS, DIAG, 'Y', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| END IF | |||
| * Find largest absolute value entry in the vector segment | |||
| * X( J1:J2-1, RHS ) as an upper bound for the worst case | |||
| * growth in the linear updates. | |||
| XNRM( KK ) = SLANGE( 'I', J2-J1, 1, X( J1, RHS ), | |||
| $ LDX, W ) | |||
| * | |||
| IF( SCALOC .EQ. ZERO ) THEN | |||
| * LATRS found that A is singular through A(j,j) = 0. | |||
| * Reset the computation x(1:n) = 0, x(j) = 1, SCALE = 0 | |||
| * and compute A*x = 0 (or A**T*x = 0). Note that | |||
| * X(J1:J2-1, KK) is set by LATRS. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, J1-1 | |||
| X( II, KK ) = ZERO | |||
| END DO | |||
| DO II = J2, N | |||
| X( II, KK ) = ZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| ELSE IF( SCALOC*WORK( J+KK*LDS ) .EQ. ZERO ) THEN | |||
| * LATRS computed a valid scale factor, but combined with | |||
| * the current scaling the solution does not have a | |||
| * scale factor > 0. | |||
| * | |||
| * Set WORK( J+KK*LDS ) to smallest valid scale | |||
| * factor and increase SCALOC accordingly. | |||
| SCAL = WORK( J+KK*LDS ) / SMLNUM | |||
| SCALOC = SCALOC * SCAL | |||
| WORK( J+KK*LDS ) = SMLNUM | |||
| * If LATRS overestimated the growth, x may be | |||
| * rescaled to preserve a valid combined scale | |||
| * factor WORK( J, KK ) > 0. | |||
| RSCAL = ONE / SCALOC | |||
| IF( XNRM( KK )*RSCAL .LE. BIGNUM ) THEN | |||
| XNRM( KK ) = XNRM( KK ) * RSCAL | |||
| CALL SSCAL( J2-J1, RSCAL, X( J1, RHS ), 1 ) | |||
| SCALOC = ONE | |||
| ELSE | |||
| * The system op(A) * x = b is badly scaled and its | |||
| * solution cannot be represented as (1/scale) * x. | |||
| * Set x to zero. This approach deviates from LATRS | |||
| * where a completely meaningless non-zero vector | |||
| * is returned that is not a solution to op(A) * x = b. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, N | |||
| X( II, KK ) = ZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| END IF | |||
| END IF | |||
| SCALOC = SCALOC * WORK( J+KK*LDS ) | |||
| WORK( J+KK*LDS ) = SCALOC | |||
| END DO | |||
| * | |||
| * Linear block updates | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| IF( UPPER ) THEN | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| END IF | |||
| ELSE | |||
| IF( UPPER ) THEN | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| ELSE | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| END IF | |||
| END IF | |||
| * | |||
| DO I = IFIRST, ILAST, IINC | |||
| * I1: row index of the first column in X( I, K ) | |||
| * I2: row index of the first column in X( I+1, K ) | |||
| * so the I2 - I1 is the row count of the block X( I, K ) | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Prepare the linear update to be executed with GEMM. | |||
| * For each column, compute a consistent scaling, a | |||
| * scaling factor to survive the linear update, and | |||
| * rescale the column segments, if necesssary. Then | |||
| * the linear update is safely executed. | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| * Compute consistent scaling | |||
| SCAMIN = MIN( WORK( I+KK*LDS), WORK( J+KK*LDS ) ) | |||
| * | |||
| * Compute scaling factor to survive the linear update | |||
| * simulating consistent scaling. | |||
| * | |||
| BNRM = SLANGE( 'I', I2-I1, 1, X( I1, RHS ), LDX, W ) | |||
| BNRM = BNRM*( SCAMIN / WORK( I+KK*LDS ) ) | |||
| XNRM( KK ) = XNRM( KK )*(SCAMIN / WORK( J+KK*LDS )) | |||
| ANRM = WORK( AWRK + I+(J-1)*NBA ) | |||
| SCALOC = SLARMM( ANRM, XNRM( KK ), BNRM ) | |||
| * | |||
| * Simultaneously apply the robust update factor and the | |||
| * consistency scaling factor to B( I, KK ) and B( J, KK ). | |||
| * | |||
| SCAL = ( SCAMIN / WORK( I+KK*LDS) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL SSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| WORK( I+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| * | |||
| SCAL = ( SCAMIN / WORK( J+KK*LDS ) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL SSCAL( J2-J1, SCAL, X( J1, RHS ), 1 ) | |||
| WORK( J+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J ) * X( J, K ) | |||
| * | |||
| CALL SGEMM( 'N', 'N', I2-I1, K2-K1, J2-J1, -ONE, | |||
| $ A( I1, J1 ), LDA, X( J1, K1 ), LDX, | |||
| $ ONE, X( I1, K1 ), LDX ) | |||
| ELSE | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J )**T * X( J, K ) | |||
| * | |||
| CALL SGEMM( 'T', 'N', I2-I1, K2-K1, J2-J1, -ONE, | |||
| $ A( J1, I1 ), LDA, X( J1, K1 ), LDX, | |||
| $ ONE, X( I1, K1 ), LDX ) | |||
| END IF | |||
| END DO | |||
| END DO | |||
| * | |||
| * Reduce local scaling factors | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| DO I = 1, NBA | |||
| SCALE( RHS ) = MIN( SCALE( RHS ), WORK( I+KK*LDS ) ) | |||
| END DO | |||
| END DO | |||
| * | |||
| * Realize consistent scaling | |||
| * | |||
| DO KK = 1, K2-K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( SCALE( RHS ).NE.ONE .AND. SCALE( RHS ).NE. ZERO ) THEN | |||
| DO I = 1, NBA | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| SCAL = SCALE( RHS ) / WORK( I+KK*LDS ) | |||
| IF( SCAL.NE.ONE ) | |||
| $ CALL SSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| END DO | |||
| END IF | |||
| END DO | |||
| END DO | |||
| RETURN | |||
| * | |||
| * End of SLATRS3 | |||
| * | |||
| END | |||
| @@ -0,0 +1,667 @@ | |||
| *> \brief \b ZLATRS3 solves a triangular system of equations with the scale factors set to prevent overflow. | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE ZLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| * X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER DIAG, NORMIN, TRANS, UPLO | |||
| * INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION CNORM( * ), SCALE( * ), WORK( * ) | |||
| * COMPLEX*16 A( LDA, * ), X( LDX, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> ZLATRS3 solves one of the triangular systems | |||
| *> | |||
| *> A * X = B * diag(scale), A**T * X = B * diag(scale), or | |||
| *> A**H * X = B * diag(scale) | |||
| *> | |||
| *> with scaling to prevent overflow. Here A is an upper or lower | |||
| *> triangular matrix, A**T denotes the transpose of A, A**H denotes the | |||
| *> conjugate transpose of A. X and B are n-by-nrhs matrices and scale | |||
| *> is an nrhs-element vector of scaling factors. A scaling factor scale(j) | |||
| *> is usually less than or equal to 1, chosen such that X(:,j) is less | |||
| *> than the overflow threshold. If the matrix A is singular (A(j,j) = 0 | |||
| *> for some j), then a non-trivial solution to A*X = 0 is returned. If | |||
| *> the system is so badly scaled that the solution cannot be represented | |||
| *> as (1/scale(k))*X(:,k), then x(:,k) = 0 and scale(k) is returned. | |||
| *> | |||
| *> This is a BLAS-3 version of LATRS for solving several right | |||
| *> hand sides simultaneously. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the matrix A is upper or lower triangular. | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] TRANS | |||
| *> \verbatim | |||
| *> TRANS is CHARACTER*1 | |||
| *> Specifies the operation applied to A. | |||
| *> = 'N': Solve A * x = s*b (No transpose) | |||
| *> = 'T': Solve A**T* x = s*b (Transpose) | |||
| *> = 'C': Solve A**T* x = s*b (Conjugate transpose) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] DIAG | |||
| *> \verbatim | |||
| *> DIAG is CHARACTER*1 | |||
| *> Specifies whether or not the matrix A is unit triangular. | |||
| *> = 'N': Non-unit triangular | |||
| *> = 'U': Unit triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NORMIN | |||
| *> \verbatim | |||
| *> NORMIN is CHARACTER*1 | |||
| *> Specifies whether CNORM has been set or not. | |||
| *> = 'Y': CNORM contains the column norms on entry | |||
| *> = 'N': CNORM is not set on entry. On exit, the norms will | |||
| *> be computed and stored in CNORM. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of columns of X. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is COMPLEX*16 array, dimension (LDA,N) | |||
| *> The triangular matrix A. If UPLO = 'U', the leading n by n | |||
| *> upper triangular part of the array A contains the upper | |||
| *> triangular matrix, and the strictly lower triangular part of | |||
| *> A is not referenced. If UPLO = 'L', the leading n by n lower | |||
| *> triangular part of the array A contains the lower triangular | |||
| *> matrix, and the strictly upper triangular part of A is not | |||
| *> referenced. If DIAG = 'U', the diagonal elements of A are | |||
| *> also not referenced and are assumed to be 1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X | |||
| *> \verbatim | |||
| *> X is COMPLEX*16 array, dimension (LDX,NRHS) | |||
| *> On entry, the right hand side B of the triangular system. | |||
| *> On exit, X is overwritten by the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX | |||
| *> \verbatim | |||
| *> LDX is INTEGER | |||
| *> The leading dimension of the array X. LDX >= max (1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] SCALE | |||
| *> \verbatim | |||
| *> SCALE is DOUBLE PRECISION array, dimension (NRHS) | |||
| *> The scaling factor s(k) is for the triangular system | |||
| *> A * x(:,k) = s(k)*b(:,k) or A**T* x(:,k) = s(k)*b(:,k). | |||
| *> If SCALE = 0, the matrix A is singular or badly scaled. | |||
| *> If A(j,j) = 0 is encountered, a non-trivial vector x(:,k) | |||
| *> that is an exact or approximate solution to A*x(:,k) = 0 | |||
| *> is returned. If the system so badly scaled that solution | |||
| *> cannot be presented as x(:,k) * 1/s(k), then x(:,k) = 0 | |||
| *> is returned. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] CNORM | |||
| *> \verbatim | |||
| *> CNORM is DOUBLE PRECISION array, dimension (N) | |||
| *> | |||
| *> If NORMIN = 'Y', CNORM is an input argument and CNORM(j) | |||
| *> contains the norm of the off-diagonal part of the j-th column | |||
| *> of A. If TRANS = 'N', CNORM(j) must be greater than or equal | |||
| *> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) | |||
| *> must be greater than or equal to the 1-norm. | |||
| *> | |||
| *> If NORMIN = 'N', CNORM is an output argument and CNORM(j) | |||
| *> returns the 1-norm of the offdiagonal part of the j-th column | |||
| *> of A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal size of | |||
| *> WORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> LWORK is INTEGER | |||
| *> LWORK >= MAX(1, 2*NBA * MAX(NBA, MIN(NRHS, 32)), where | |||
| *> NBA = (N + NB - 1)/NB and NB is the optimal block size. | |||
| *> | |||
| *> If LWORK = -1, then a workspace query is assumed; the routine | |||
| *> only calculates the optimal dimensions of the WORK array, returns | |||
| *> this value as the first entry of the WORK array, and no error | |||
| *> message related to LWORK is issued by XERBLA. | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \ingroup doubleOTHERauxiliary | |||
| *> \par Further Details: | |||
| * ===================== | |||
| * \verbatim | |||
| * The algorithm follows the structure of a block triangular solve. | |||
| * The diagonal block is solved with a call to the robust the triangular | |||
| * solver LATRS for every right-hand side RHS = 1, ..., NRHS | |||
| * op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ), | |||
| * where op( A ) = A or op( A ) = A**T or op( A ) = A**H. | |||
| * The linear block updates operate on block columns of X, | |||
| * B( I, K ) - op(A( I, J )) * X( J, K ) | |||
| * and use GEMM. To avoid overflow in the linear block update, the worst case | |||
| * growth is estimated. For every RHS, a scale factor s <= 1.0 is computed | |||
| * such that | |||
| * || s * B( I, RHS )||_oo | |||
| * + || op(A( I, J )) ||_oo * || s * X( J, RHS ) ||_oo <= Overflow threshold | |||
| * | |||
| * Once all columns of a block column have been rescaled (BLAS-1), the linear | |||
| * update is executed with GEMM without overflow. | |||
| * | |||
| * To limit rescaling, local scale factors track the scaling of column segments. | |||
| * There is one local scale factor s( I, RHS ) per block row I = 1, ..., NBA | |||
| * per right-hand side column RHS = 1, ..., NRHS. The global scale factor | |||
| * SCALE( RHS ) is chosen as the smallest local scale factor s( I, RHS ) | |||
| * I = 1, ..., NBA. | |||
| * A triangular solve op(A( J, J )) * x( J, RHS ) = SCALOC * b( J, RHS ) | |||
| * updates the local scale factor s( J, RHS ) := s( J, RHS ) * SCALOC. The | |||
| * linear update of potentially inconsistently scaled vector segments | |||
| * s( I, RHS ) * b( I, RHS ) - op(A( I, J )) * ( s( J, RHS )* x( J, RHS ) ) | |||
| * computes a consistent scaling SCAMIN = MIN( s(I, RHS ), s(J, RHS) ) and, | |||
| * if necessary, rescales the blocks prior to calling GEMM. | |||
| * | |||
| * \endverbatim | |||
| * ===================================================================== | |||
| * References: | |||
| * C. C. Kjelgaard Mikkelsen, A. B. Schwarz and L. Karlsson (2019). | |||
| * Parallel robust solution of triangular linear systems. Concurrency | |||
| * and Computation: Practice and Experience, 31(19), e5064. | |||
| * | |||
| * Contributor: | |||
| * Angelika Schwarz, Umea University, Sweden. | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE ZLATRS3( UPLO, TRANS, DIAG, NORMIN, N, NRHS, A, LDA, | |||
| $ X, LDX, SCALE, CNORM, WORK, LWORK, INFO ) | |||
| IMPLICIT NONE | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER DIAG, TRANS, NORMIN, UPLO | |||
| INTEGER INFO, LDA, LWORK, LDX, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| COMPLEX*16 A( LDA, * ), X( LDX, * ) | |||
| DOUBLE PRECISION CNORM( * ), SCALE( * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) | |||
| COMPLEX*16 CZERO, CONE | |||
| PARAMETER ( CONE = ( 1.0D+0, 0.0D+0 ) ) | |||
| PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ) ) | |||
| INTEGER NBMAX, NBMIN, NBRHS, NRHSMIN | |||
| PARAMETER ( NRHSMIN = 2, NBRHS = 32 ) | |||
| PARAMETER ( NBMIN = 8, NBMAX = 64 ) | |||
| * .. | |||
| * .. Local Arrays .. | |||
| DOUBLE PRECISION W( NBMAX ), XNRM( NBRHS ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER | |||
| INTEGER AWRK, I, IFIRST, IINC, ILAST, II, I1, I2, J, | |||
| $ JFIRST, JINC, JLAST, J1, J2, K, KK, K1, K2, | |||
| $ LANRM, LDS, LSCALE, NB, NBA, NBX, RHS | |||
| DOUBLE PRECISION ANRM, BIGNUM, BNRM, RSCAL, SCAL, SCALOC, | |||
| $ SCAMIN, SMLNUM, TMAX | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| DOUBLE PRECISION DLAMCH, ZLANGE, DLARMM | |||
| EXTERNAL ILAENV, LSAME, DLAMCH, ZLANGE, DLARMM | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ZLATRS, ZDSCAL, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, MIN | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| NOTRAN = LSAME( TRANS, 'N' ) | |||
| NOUNIT = LSAME( DIAG, 'N' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| * | |||
| * Partition A and X into blocks. | |||
| * | |||
| NB = MAX( NBMIN, ILAENV( 1, 'ZLATRS', '', N, N, -1, -1 ) ) | |||
| NB = MIN( NBMAX, NB ) | |||
| NBA = MAX( 1, (N + NB - 1) / NB ) | |||
| NBX = MAX( 1, (NRHS + NBRHS - 1) / NBRHS ) | |||
| * | |||
| * Compute the workspace | |||
| * | |||
| * The workspace comprises two parts. | |||
| * The first part stores the local scale factors. Each simultaneously | |||
| * computed right-hand side requires one local scale factor per block | |||
| * row. WORK( I + KK * LDS ) is the scale factor of the vector | |||
| * segment associated with the I-th block row and the KK-th vector | |||
| * in the block column. | |||
| LSCALE = NBA * MAX( NBA, MIN( NRHS, NBRHS ) ) | |||
| LDS = NBA | |||
| * The second part stores upper bounds of the triangular A. There are | |||
| * a total of NBA x NBA blocks, of which only the upper triangular | |||
| * part or the lower triangular part is referenced. The upper bound of | |||
| * the block A( I, J ) is stored as WORK( AWRK + I + J * NBA ). | |||
| LANRM = NBA * NBA | |||
| AWRK = LSCALE | |||
| WORK( 1 ) = LSCALE + LANRM | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. | |||
| $ LSAME( TRANS, 'C' ) ) THEN | |||
| INFO = -2 | |||
| ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN | |||
| INFO = -3 | |||
| ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT. | |||
| $ LSAME( NORMIN, 'N' ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LDX.LT.MAX( 1, N ) ) THEN | |||
| INFO = -10 | |||
| ELSE IF( .NOT.LQUERY .AND. LWORK.LT.WORK( 1 ) ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'ZLATRS3', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize scaling factors | |||
| * | |||
| DO KK = 1, NRHS | |||
| SCALE( KK ) = ONE | |||
| END DO | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( MIN( N, NRHS ).EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Determine machine dependent constant to control overflow. | |||
| * | |||
| BIGNUM = DLAMCH( 'Overflow' ) | |||
| SMLNUM = DLAMCH( 'Safe Minimum' ) | |||
| * | |||
| * Use unblocked code for small problems | |||
| * | |||
| IF( NRHS.LT.NRHSMIN ) THEN | |||
| CALL ZLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X( 1, 1), | |||
| $ SCALE( 1 ), CNORM, INFO ) | |||
| DO K = 2, NRHS | |||
| CALL ZLATRS( UPLO, TRANS, DIAG, 'Y', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute norms of blocks of A excluding diagonal blocks and find | |||
| * the block with the largest norm TMAX. | |||
| * | |||
| TMAX = ZERO | |||
| DO J = 1, NBA | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| IF ( UPPER ) THEN | |||
| IFIRST = 1 | |||
| ILAST = J - 1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| END IF | |||
| DO I = IFIRST, ILAST | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Compute upper bound of A( I1:I2-1, J1:J2-1 ). | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| ANRM = ZLANGE( 'I', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + I+(J-1)*NBA ) = ANRM | |||
| ELSE | |||
| ANRM = ZLANGE( '1', I2-I1, J2-J1, A( I1, J1 ), LDA, W ) | |||
| WORK( AWRK + J+(I-1) * NBA ) = ANRM | |||
| END IF | |||
| TMAX = MAX( TMAX, ANRM ) | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( .NOT. TMAX.LE.DLAMCH('Overflow') ) THEN | |||
| * | |||
| * Some matrix entries have huge absolute value. At least one upper | |||
| * bound norm( A(I1:I2-1, J1:J2-1), 'I') is not a valid floating-point | |||
| * number, either due to overflow in LANGE or due to Inf in A. | |||
| * Fall back to LATRS. Set normin = 'N' for every right-hand side to | |||
| * force computation of TSCAL in LATRS to avoid the likely overflow | |||
| * in the computation of the column norms CNORM. | |||
| * | |||
| DO K = 1, NRHS | |||
| CALL ZLATRS( UPLO, TRANS, DIAG, 'N', N, A, LDA, X( 1, K ), | |||
| $ SCALE( K ), CNORM, INFO ) | |||
| END DO | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Every right-hand side requires workspace to store NBA local scale | |||
| * factors. To save workspace, X is computed successively in block columns | |||
| * of width NBRHS, requiring a total of NBA x NBRHS space. If sufficient | |||
| * workspace is available, larger values of NBRHS or NBRHS = NRHS are viable. | |||
| DO K = 1, NBX | |||
| * Loop over block columns (index = K) of X and, for column-wise scalings, | |||
| * over individual columns (index = KK). | |||
| * K1: column index of the first column in X( J, K ) | |||
| * K2: column index of the first column in X( J, K+1 ) | |||
| * so the K2 - K1 is the column count of the block X( J, K ) | |||
| K1 = (K-1)*NBRHS + 1 | |||
| K2 = MIN( K*NBRHS, NRHS ) + 1 | |||
| * | |||
| * Initialize local scaling factors of current block column X( J, K ) | |||
| * | |||
| DO KK = 1, K2 - K1 | |||
| DO I = 1, NBA | |||
| WORK( I+KK*LDS ) = ONE | |||
| END DO | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * Solve A * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| ELSE | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Solve op(A) * X(:, K1:K2-1) = B * diag(scale(K1:K2-1)) | |||
| * where op(A) = A**T or op(A) = A**H | |||
| * | |||
| IF( UPPER ) THEN | |||
| JFIRST = 1 | |||
| JLAST = NBA | |||
| JINC = 1 | |||
| ELSE | |||
| JFIRST = NBA | |||
| JLAST = 1 | |||
| JINC = -1 | |||
| END IF | |||
| END IF | |||
| DO J = JFIRST, JLAST, JINC | |||
| * J1: row index of the first row in A( J, J ) | |||
| * J2: row index of the first row in A( J+1, J+1 ) | |||
| * so that J2 - J1 is the row count of the block A( J, J ) | |||
| J1 = (J-1)*NB + 1 | |||
| J2 = MIN( J*NB, N ) + 1 | |||
| * | |||
| * Solve op(A( J, J )) * X( J, RHS ) = SCALOC * B( J, RHS ) | |||
| * | |||
| DO KK = 1, K2 - K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( KK.EQ.1 ) THEN | |||
| CALL ZLATRS( UPLO, TRANS, DIAG, 'N', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| ELSE | |||
| CALL ZLATRS( UPLO, TRANS, DIAG, 'Y', J2-J1, | |||
| $ A( J1, J1 ), LDA, X( J1, RHS ), | |||
| $ SCALOC, CNORM, INFO ) | |||
| END IF | |||
| * Find largest absolute value entry in the vector segment | |||
| * X( J1:J2-1, RHS ) as an upper bound for the worst case | |||
| * growth in the linear updates. | |||
| XNRM( KK ) = ZLANGE( 'I', J2-J1, 1, X( J1, RHS ), | |||
| $ LDX, W ) | |||
| * | |||
| IF( SCALOC .EQ. ZERO ) THEN | |||
| * LATRS found that A is singular through A(j,j) = 0. | |||
| * Reset the computation x(1:n) = 0, x(j) = 1, SCALE = 0 | |||
| * and compute op(A)*x = 0. Note that X(J1:J2-1, KK) is | |||
| * set by LATRS. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, J1-1 | |||
| X( II, KK ) = CZERO | |||
| END DO | |||
| DO II = J2, N | |||
| X( II, KK ) = CZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| ELSE IF( SCALOC*WORK( J+KK*LDS ) .EQ. ZERO ) THEN | |||
| * LATRS computed a valid scale factor, but combined with | |||
| * the current scaling the solution does not have a | |||
| * scale factor > 0. | |||
| * | |||
| * Set WORK( J+KK*LDS ) to smallest valid scale | |||
| * factor and increase SCALOC accordingly. | |||
| SCAL = WORK( J+KK*LDS ) / SMLNUM | |||
| SCALOC = SCALOC * SCAL | |||
| WORK( J+KK*LDS ) = SMLNUM | |||
| * If LATRS overestimated the growth, x may be | |||
| * rescaled to preserve a valid combined scale | |||
| * factor WORK( J, KK ) > 0. | |||
| RSCAL = ONE / SCALOC | |||
| IF( XNRM( KK )*RSCAL .LE. BIGNUM ) THEN | |||
| XNRM( KK ) = XNRM( KK ) * RSCAL | |||
| CALL ZDSCAL( J2-J1, RSCAL, X( J1, RHS ), 1 ) | |||
| SCALOC = ONE | |||
| ELSE | |||
| * The system op(A) * x = b is badly scaled and its | |||
| * solution cannot be represented as (1/scale) * x. | |||
| * Set x to zero. This approach deviates from LATRS | |||
| * where a completely meaningless non-zero vector | |||
| * is returned that is not a solution to op(A) * x = b. | |||
| SCALE( RHS ) = ZERO | |||
| DO II = 1, N | |||
| X( II, KK ) = CZERO | |||
| END DO | |||
| * Discard the local scale factors. | |||
| DO II = 1, NBA | |||
| WORK( II+KK*LDS ) = ONE | |||
| END DO | |||
| SCALOC = ONE | |||
| END IF | |||
| END IF | |||
| SCALOC = SCALOC * WORK( J+KK*LDS ) | |||
| WORK( J+KK*LDS ) = SCALOC | |||
| END DO | |||
| * | |||
| * Linear block updates | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| IF( UPPER ) THEN | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| ELSE | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| END IF | |||
| ELSE | |||
| IF( UPPER ) THEN | |||
| IFIRST = J + 1 | |||
| ILAST = NBA | |||
| IINC = 1 | |||
| ELSE | |||
| IFIRST = J - 1 | |||
| ILAST = 1 | |||
| IINC = -1 | |||
| END IF | |||
| END IF | |||
| * | |||
| DO I = IFIRST, ILAST, IINC | |||
| * I1: row index of the first column in X( I, K ) | |||
| * I2: row index of the first column in X( I+1, K ) | |||
| * so the I2 - I1 is the row count of the block X( I, K ) | |||
| I1 = (I-1)*NB + 1 | |||
| I2 = MIN( I*NB, N ) + 1 | |||
| * | |||
| * Prepare the linear update to be executed with GEMM. | |||
| * For each column, compute a consistent scaling, a | |||
| * scaling factor to survive the linear update, and | |||
| * rescale the column segments, if necesssary. Then | |||
| * the linear update is safely executed. | |||
| * | |||
| DO KK = 1, K2 - K1 | |||
| RHS = K1 + KK - 1 | |||
| * Compute consistent scaling | |||
| SCAMIN = MIN( WORK( I+KK*LDS), WORK( J+KK*LDS ) ) | |||
| * | |||
| * Compute scaling factor to survive the linear update | |||
| * simulating consistent scaling. | |||
| * | |||
| BNRM = ZLANGE( 'I', I2-I1, 1, X( I1, RHS ), LDX, W ) | |||
| BNRM = BNRM*( SCAMIN / WORK( I+KK*LDS ) ) | |||
| XNRM( KK ) = XNRM( KK )*( SCAMIN / WORK( J+KK*LDS) ) | |||
| ANRM = WORK( AWRK + I+(J-1)*NBA ) | |||
| SCALOC = DLARMM( ANRM, XNRM( KK ), BNRM ) | |||
| * | |||
| * Simultaneously apply the robust update factor and the | |||
| * consistency scaling factor to X( I, KK ) and X( J, KK ). | |||
| * | |||
| SCAL = ( SCAMIN / WORK( I+KK*LDS) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL ZDSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| WORK( I+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| * | |||
| SCAL = ( SCAMIN / WORK( J+KK*LDS ) )*SCALOC | |||
| IF( SCAL.NE.ONE ) THEN | |||
| CALL ZDSCAL( J2-J1, SCAL, X( J1, RHS ), 1 ) | |||
| WORK( J+KK*LDS ) = SCAMIN*SCALOC | |||
| END IF | |||
| END DO | |||
| * | |||
| IF( NOTRAN ) THEN | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J ) * X( J, K ) | |||
| * | |||
| CALL ZGEMM( 'N', 'N', I2-I1, K2-K1, J2-J1, -CONE, | |||
| $ A( I1, J1 ), LDA, X( J1, K1 ), LDX, | |||
| $ CONE, X( I1, K1 ), LDX ) | |||
| ELSE IF( LSAME( TRANS, 'T' ) ) THEN | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J )**T * X( J, K ) | |||
| * | |||
| CALL ZGEMM( 'T', 'N', I2-I1, K2-K1, J2-J1, -CONE, | |||
| $ A( J1, I1 ), LDA, X( J1, K1 ), LDX, | |||
| $ CONE, X( I1, K1 ), LDX ) | |||
| ELSE | |||
| * | |||
| * B( I, K ) := B( I, K ) - A( I, J )**H * X( J, K ) | |||
| * | |||
| CALL ZGEMM( 'C', 'N', I2-I1, K2-K1, J2-J1, -CONE, | |||
| $ A( J1, I1 ), LDA, X( J1, K1 ), LDX, | |||
| $ CONE, X( I1, K1 ), LDX ) | |||
| END IF | |||
| END DO | |||
| END DO | |||
| * | |||
| * Reduce local scaling factors | |||
| * | |||
| DO KK = 1, K2 - K1 | |||
| RHS = K1 + KK - 1 | |||
| DO I = 1, NBA | |||
| SCALE( RHS ) = MIN( SCALE( RHS ), WORK( I+KK*LDS ) ) | |||
| END DO | |||
| END DO | |||
| * | |||
| * Realize consistent scaling | |||
| * | |||
| DO KK = 1, K2 - K1 | |||
| RHS = K1 + KK - 1 | |||
| IF( SCALE( RHS ).NE.ONE .AND. SCALE( RHS ).NE. ZERO ) THEN | |||
| DO I = 1, NBA | |||
| I1 = (I - 1) * NB + 1 | |||
| I2 = MIN( I * NB, N ) + 1 | |||
| SCAL = SCALE( RHS ) / WORK( I+KK*LDS ) | |||
| IF( SCAL.NE.ONE ) | |||
| $ CALL ZDSCAL( I2-I1, SCAL, X( I1, RHS ), 1 ) | |||
| END DO | |||
| END IF | |||
| END DO | |||
| END DO | |||
| RETURN | |||
| * | |||
| * End of ZLATRS3 | |||
| * | |||
| END | |||
| @@ -40,7 +40,7 @@ set(SEIGTST schkee.F | |||
| sget54.f sglmts.f sgqrts.f sgrqts.f sgsvts3.f | |||
| shst01.f slarfy.f slarhs.f slatm4.f slctes.f slctsx.f slsets.f sort01.f | |||
| sort03.f ssbt21.f ssgt01.f sslect.f sspt21.f sstt21.f | |||
| sstt22.f ssyt21.f ssyt22.f) | |||
| sstt22.f ssyl01.f ssyt21.f ssyt22.f) | |||
| set(CEIGTST cchkee.F | |||
| cbdt01.f cbdt02.f cbdt03.f cbdt05.f | |||
| @@ -56,7 +56,7 @@ set(CEIGTST cchkee.F | |||
| cget54.f cglmts.f cgqrts.f cgrqts.f cgsvts3.f | |||
| chbt21.f chet21.f chet22.f chpt21.f chst01.f | |||
| clarfy.f clarhs.f clatm4.f clctes.f clctsx.f clsets.f csbmv.f | |||
| csgt01.f cslect.f | |||
| csgt01.f cslect.f csyl01.f | |||
| cstt21.f cstt22.f cunt01.f cunt03.f) | |||
| set(DZIGTST dlafts.f dlahd2.f dlasum.f dlatb9.f dstech.f dstect.f | |||
| @@ -77,7 +77,7 @@ set(DEIGTST dchkee.F | |||
| dget54.f dglmts.f dgqrts.f dgrqts.f dgsvts3.f | |||
| dhst01.f dlarfy.f dlarhs.f dlatm4.f dlctes.f dlctsx.f dlsets.f dort01.f | |||
| dort03.f dsbt21.f dsgt01.f dslect.f dspt21.f dstt21.f | |||
| dstt22.f dsyt21.f dsyt22.f) | |||
| dstt22.f dsyl01.f dsyt21.f dsyt22.f) | |||
| set(ZEIGTST zchkee.F | |||
| zbdt01.f zbdt02.f zbdt03.f zbdt05.f | |||
| @@ -93,7 +93,7 @@ set(ZEIGTST zchkee.F | |||
| zget54.f zglmts.f zgqrts.f zgrqts.f zgsvts3.f | |||
| zhbt21.f zhet21.f zhet22.f zhpt21.f zhst01.f | |||
| zlarfy.f zlarhs.f zlatm4.f zlctes.f zlctsx.f zlsets.f zsbmv.f | |||
| zsgt01.f zslect.f | |||
| zsgt01.f zslect.f zsyl01.f | |||
| zstt21.f zstt22.f zunt01.f zunt03.f) | |||
| macro(add_eig_executable name) | |||
| @@ -62,7 +62,7 @@ SEIGTST = schkee.o \ | |||
| sget54.o sglmts.o sgqrts.o sgrqts.o sgsvts3.o \ | |||
| shst01.o slarfy.o slarhs.o slatm4.o slctes.o slctsx.o slsets.o sort01.o \ | |||
| sort03.o ssbt21.o ssgt01.o sslect.o sspt21.o sstt21.o \ | |||
| sstt22.o ssyt21.o ssyt22.o | |||
| sstt22.o ssyl01.o ssyt21.o ssyt22.o | |||
| CEIGTST = cchkee.o \ | |||
| cbdt01.o cbdt02.o cbdt03.o cbdt05.o \ | |||
| @@ -78,7 +78,7 @@ CEIGTST = cchkee.o \ | |||
| cget54.o cglmts.o cgqrts.o cgrqts.o cgsvts3.o \ | |||
| chbt21.o chet21.o chet22.o chpt21.o chst01.o \ | |||
| clarfy.o clarhs.o clatm4.o clctes.o clctsx.o clsets.o csbmv.o \ | |||
| csgt01.o cslect.o \ | |||
| csgt01.o cslect.o csyl01.o\ | |||
| cstt21.o cstt22.o cunt01.o cunt03.o | |||
| DZIGTST = dlafts.o dlahd2.o dlasum.o dlatb9.o dstech.o dstect.o \ | |||
| @@ -99,7 +99,7 @@ DEIGTST = dchkee.o \ | |||
| dget54.o dglmts.o dgqrts.o dgrqts.o dgsvts3.o \ | |||
| dhst01.o dlarfy.o dlarhs.o dlatm4.o dlctes.o dlctsx.o dlsets.o dort01.o \ | |||
| dort03.o dsbt21.o dsgt01.o dslect.o dspt21.o dstt21.o \ | |||
| dstt22.o dsyt21.o dsyt22.o | |||
| dstt22.o dsyl01.o dsyt21.o dsyt22.o | |||
| ZEIGTST = zchkee.o \ | |||
| zbdt01.o zbdt02.o zbdt03.o zbdt05.o \ | |||
| @@ -115,7 +115,7 @@ ZEIGTST = zchkee.o \ | |||
| zget54.o zglmts.o zgqrts.o zgrqts.o zgsvts3.o \ | |||
| zhbt21.o zhet21.o zhet22.o zhpt21.o zhst01.o \ | |||
| zlarfy.o zlarhs.o zlatm4.o zlctes.o zlctsx.o zlsets.o zsbmv.o \ | |||
| zsgt01.o zslect.o \ | |||
| zsgt01.o zslect.o zsyl01.o\ | |||
| zstt21.o zstt22.o zunt01.o zunt03.o | |||
| .PHONY: all | |||
| @@ -23,7 +23,7 @@ | |||
| *> \verbatim | |||
| *> | |||
| *> CCHKEC tests eigen- condition estimation routines | |||
| *> CTRSYL, CTREXC, CTRSNA, CTRSEN | |||
| *> CTRSYL, CTRSYL3, CTREXC, CTRSNA, CTRSEN | |||
| *> | |||
| *> In all cases, the routine runs through a fixed set of numerical | |||
| *> examples, subjects them to various tests, and compares the test | |||
| @@ -88,17 +88,17 @@ | |||
| * .. Local Scalars .. | |||
| LOGICAL OK | |||
| CHARACTER*3 PATH | |||
| INTEGER KTREXC, KTRSEN, KTRSNA, KTRSYL, LTREXC, LTRSYL, | |||
| $ NTESTS, NTREXC, NTRSYL | |||
| REAL EPS, RTREXC, RTRSYL, SFMIN | |||
| INTEGER KTREXC, KTRSEN, KTRSNA, KTRSYL, KTRSYL3, | |||
| $ LTREXC, LTRSYL, NTESTS, NTREXC, NTRSYL | |||
| REAL EPS, RTREXC, SFMIN | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER LTRSEN( 3 ), LTRSNA( 3 ), NTRSEN( 3 ), | |||
| $ NTRSNA( 3 ) | |||
| REAL RTRSEN( 3 ), RTRSNA( 3 ) | |||
| INTEGER FTRSYL( 3 ), ITRSYL( 2 ), LTRSEN( 3 ), | |||
| $ LTRSNA( 3 ), NTRSEN( 3 ), NTRSNA( 3 ) | |||
| REAL RTRSEN( 3 ), RTRSNA( 3 ), RTRSYL( 2 ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CERREC, CGET35, CGET36, CGET37, CGET38 | |||
| EXTERNAL CERREC, CGET35, CGET36, CGET37, CGET38, CSYL01 | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SLAMCH | |||
| @@ -120,10 +120,24 @@ | |||
| $ CALL CERREC( PATH, NOUT ) | |||
| * | |||
| OK = .TRUE. | |||
| CALL CGET35( RTRSYL, LTRSYL, NTRSYL, KTRSYL, NIN ) | |||
| IF( RTRSYL.GT.THRESH ) THEN | |||
| CALL CGET35( RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL, NIN ) | |||
| IF( RTRSYL( 1 ).GT.THRESH ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9999 )RTRSYL, LTRSYL, NTRSYL, KTRSYL | |||
| WRITE( NOUT, FMT = 9999 )RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL | |||
| END IF | |||
| * | |||
| CALL CSYL01( THRESH, FTRSYL, RTRSYL, ITRSYL, KTRSYL3 ) | |||
| IF( FTRSYL( 1 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9970 )FTRSYL( 1 ), RTRSYL( 1 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 2 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9971 )FTRSYL( 2 ), RTRSYL( 2 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 3 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9972 )FTRSYL( 3 ) | |||
| END IF | |||
| * | |||
| CALL CGET36( RTREXC, LTREXC, NTREXC, KTREXC, NIN ) | |||
| @@ -169,6 +183,12 @@ | |||
| $ / ' Safe minimum (SFMIN) = ', E16.6, / ) | |||
| 9992 FORMAT( ' Routines pass computational tests if test ratio is ', | |||
| $ 'less than', F8.2, / / ) | |||
| 9972 FORMAT( 'CTRSYL and CTRSYL3 compute an inconsistent scale ', | |||
| $ 'factor in ', I8, ' tests.') | |||
| 9971 FORMAT( 'Error in CTRSYL3: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| 9970 FORMAT( 'Error in CTRSYL: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| RETURN | |||
| * | |||
| * End of CCHKEC | |||
| @@ -23,7 +23,7 @@ | |||
| *> | |||
| *> CERREC tests the error exits for the routines for eigen- condition | |||
| *> estimation for REAL matrices: | |||
| *> CTRSYL, CTREXC, CTRSNA and CTRSEN. | |||
| *> CTRSYL, CTRSYL3, CTREXC, CTRSNA and CTRSEN. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -77,12 +77,12 @@ | |||
| * .. | |||
| * .. Local Arrays .. | |||
| LOGICAL SEL( NMAX ) | |||
| REAL RW( LW ), S( NMAX ), SEP( NMAX ) | |||
| REAL RW( LW ), S( NMAX ), SEP( NMAX ), SWORK( NMAX ) | |||
| COMPLEX A( NMAX, NMAX ), B( NMAX, NMAX ), | |||
| $ C( NMAX, NMAX ), WORK( LW ), X( NMAX ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CHKXER, CTREXC, CTRSEN, CTRSNA, CTRSYL | |||
| EXTERNAL CHKXER, CTREXC, CTRSEN, CTRSNA, CTRSYL, CTRSYL3 | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -141,6 +141,43 @@ | |||
| CALL CHKXER( 'CTRSYL', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test CTRSYL3 | |||
| * | |||
| SRNAMT = 'CTRSYL3' | |||
| INFOT = 1 | |||
| CALL CTRSYL3( 'X', 'N', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL CTRSYL3( 'N', 'X', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL CTRSYL3( 'N', 'N', 0, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL CTRSYL3( 'N', 'N', 1, -1, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL CTRSYL3( 'N', 'N', 1, 0, -1, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 7 | |||
| CALL CTRSYL3( 'N', 'N', 1, 2, 0, A, 1, B, 1, C, 2, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 9 | |||
| CALL CTRSYL3( 'N', 'N', 1, 0, 2, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 11 | |||
| CALL CTRSYL3( 'N', 'N', 1, 2, 0, A, 2, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'CTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test CTREXC | |||
| * | |||
| SRNAMT = 'CTREXC' | |||
| @@ -0,0 +1,294 @@ | |||
| *> \brief \b CSYL01 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER KNT | |||
| * REAL THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| * REAL RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYL01 tests CTRSYL and CTRSYL3, routines for solving the Sylvester matrix | |||
| *> equation | |||
| *> | |||
| *> op(A)*X + ISGN*X*op(B) = scale*C, | |||
| *> | |||
| *> where op(A) and op(B) are both upper triangular form, op() represents an | |||
| *> optional conjugate transpose, and ISGN can be -1 or +1. Scale is an output | |||
| *> less than or equal to 1, chosen to avoid overflow in X. | |||
| *> | |||
| *> The test code verifies that the following residual does not exceed | |||
| *> the provided threshold: | |||
| *> | |||
| *> norm(op(A)*X + ISGN*X*op(B) - scale*C) / | |||
| *> (EPS*max(norm(A),norm(B))*norm(X)) | |||
| *> | |||
| *> This routine complements CGET35 by testing with larger, | |||
| *> random matrices, of which some require rescaling of X to avoid overflow. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] THRESH | |||
| *> \verbatim | |||
| *> THRESH is REAL | |||
| *> A test will count as "failed" if the residual, computed as | |||
| *> described above, exceeds THRESH. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NFAIL | |||
| *> \verbatim | |||
| *> NFAIL is INTEGER array, dimension (3) | |||
| *> NFAIL(1) = No. of times residual CTRSYL exceeds threshold THRESH | |||
| *> NFAIL(2) = No. of times residual CTRSYL3 exceeds threshold THRESH | |||
| *> NFAIL(3) = No. of times CTRSYL3 and CTRSYL deviate | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RMAX | |||
| *> \verbatim | |||
| *> RMAX is DOUBLE PRECISION array, dimension (2) | |||
| *> RMAX(1) = Value of the largest test ratio of CTRSYL | |||
| *> RMAX(2) = Value of the largest test ratio of CTRSYL3 | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NINFO | |||
| *> \verbatim | |||
| *> NINFO is INTEGER array, dimension (2) | |||
| *> NINFO(1) = No. of times CTRSYL where INFO is nonzero | |||
| *> NINFO(2) = No. of times CTRSYL3 where INFO is nonzero | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] KNT | |||
| *> \verbatim | |||
| *> KNT is INTEGER | |||
| *> Total number of examples tested. | |||
| *> \endverbatim | |||
| * | |||
| * -- LAPACK test routine -- | |||
| SUBROUTINE CSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| IMPLICIT NONE | |||
| * | |||
| * -- LAPACK test routine -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER KNT | |||
| REAL THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| REAL RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * .. | |||
| * .. Parameters .. | |||
| COMPLEX CONE | |||
| PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) ) | |||
| REAL ONE, ZERO | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| INTEGER MAXM, MAXN, LDSWORK | |||
| PARAMETER ( MAXM = 101, MAXN = 138, LDSWORK = 18 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| CHARACTER TRANA, TRANB | |||
| INTEGER I, INFO, IINFO, ISGN, ITRANA, ITRANB, J, KLA, | |||
| $ KUA, KLB, KUB, M, N | |||
| REAL ANRM, BNRM, BIGNUM, EPS, RES, RES1, | |||
| $ SCALE, SCALE3, SMLNUM, TNRM, XNRM | |||
| COMPLEX RMUL | |||
| * .. | |||
| * .. Local Arrays .. | |||
| COMPLEX A( MAXM, MAXM ), B( MAXN, MAXN ), | |||
| $ C( MAXM, MAXN ), CC( MAXM, MAXN ), | |||
| $ X( MAXM, MAXN ), | |||
| $ DUML( MAXM ), DUMR( MAXN ), | |||
| $ D( MIN( MAXM, MAXN ) ) | |||
| REAL SWORK( LDSWORK, 54 ), DUM( MAXN ), VM( 2 ) | |||
| INTEGER ISEED( 4 ), IWORK( MAXM + MAXN + 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL SISNAN | |||
| REAL SLAMCH, CLANGE | |||
| EXTERNAL SISNAN, SLAMCH, CLANGE | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLATMR, CLACPY, CGEMM, CTRSYL, CTRSYL3 | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, REAL, MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Get machine parameters | |||
| * | |||
| EPS = SLAMCH( 'P' ) | |||
| SMLNUM = SLAMCH( 'S' ) / EPS | |||
| BIGNUM = ONE / SMLNUM | |||
| * | |||
| * Expect INFO = 0 | |||
| VM( 1 ) = ONE | |||
| * Expect INFO = 1 | |||
| VM( 2 ) = 0.5E+0 | |||
| * | |||
| * Begin test loop | |||
| * | |||
| NINFO( 1 ) = 0 | |||
| NINFO( 2 ) = 0 | |||
| NFAIL( 1 ) = 0 | |||
| NFAIL( 2 ) = 0 | |||
| NFAIL( 3 ) = 0 | |||
| RMAX( 1 ) = ZERO | |||
| RMAX( 2 ) = ZERO | |||
| KNT = 0 | |||
| ISEED( 1 ) = 1 | |||
| ISEED( 2 ) = 1 | |||
| ISEED( 3 ) = 1 | |||
| ISEED( 4 ) = 1 | |||
| SCALE = ONE | |||
| SCALE3 = ONE | |||
| DO J = 1, 2 | |||
| DO ISGN = -1, 1, 2 | |||
| * Reset seed (overwritten by LATMR) | |||
| ISEED( 1 ) = 1 | |||
| ISEED( 2 ) = 1 | |||
| ISEED( 3 ) = 1 | |||
| ISEED( 4 ) = 1 | |||
| DO M = 32, MAXM, 23 | |||
| KLA = 0 | |||
| KUA = M - 1 | |||
| CALL CLATMR( M, M, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, CONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLA, KUA, ZERO, | |||
| $ ONE, 'NO', A, MAXM, IWORK, | |||
| $ IINFO ) | |||
| DO I = 1, M | |||
| A( I, I ) = A( I, I ) * VM( J ) | |||
| END DO | |||
| ANRM = CLANGE( 'M', M, M, A, MAXM, DUM ) | |||
| DO N = 51, MAXN, 29 | |||
| KLB = 0 | |||
| KUB = N - 1 | |||
| CALL CLATMR( N, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, CONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLB, KUB, ZERO, | |||
| $ ONE, 'NO', B, MAXN, IWORK, | |||
| $ IINFO ) | |||
| DO I = 1, N | |||
| B( I, I ) = B( I, I ) * VM ( J ) | |||
| END DO | |||
| BNRM = CLANGE( 'M', N, N, B, MAXN, DUM ) | |||
| TNRM = MAX( ANRM, BNRM ) | |||
| CALL CLATMR( M, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, CONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, M, N, ZERO, ONE, | |||
| $ 'NO', C, MAXM, IWORK, IINFO ) | |||
| DO ITRANA = 1, 2 | |||
| IF( ITRANA.EQ.1 ) | |||
| $ TRANA = 'N' | |||
| IF( ITRANA.EQ.2 ) | |||
| $ TRANA = 'C' | |||
| DO ITRANB = 1, 2 | |||
| IF( ITRANB.EQ.1 ) | |||
| $ TRANB = 'N' | |||
| IF( ITRANB.EQ.2 ) | |||
| $ TRANB = 'C' | |||
| KNT = KNT + 1 | |||
| * | |||
| CALL CLACPY( 'All', M, N, C, MAXM, X, MAXM) | |||
| CALL CLACPY( 'All', M, N, C, MAXM, CC, MAXM) | |||
| CALL CTRSYL( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE, IINFO ) | |||
| IF( IINFO.NE.0 ) | |||
| $ NINFO( 1 ) = NINFO( 1 ) + 1 | |||
| XNRM = CLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = CONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = CONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL CGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL CGEMM( 'N', TRANB, M, N, N, | |||
| $ REAL( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, CONE, CC, MAXM ) | |||
| RES1 = CLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( ABS( RMUL )*TNRM )*EPS )*XNRM ) | |||
| IF( RES.GT.THRESH ) | |||
| $ NFAIL( 1 ) = NFAIL( 1 ) + 1 | |||
| IF( RES.GT.RMAX( 1 ) ) | |||
| $ RMAX( 1 ) = RES | |||
| * | |||
| CALL CLACPY( 'All', M, N, C, MAXM, X, MAXM ) | |||
| CALL CLACPY( 'All', M, N, C, MAXM, CC, MAXM ) | |||
| CALL CTRSYL3( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE3, SWORK, LDSWORK, INFO) | |||
| IF( INFO.NE.0 ) | |||
| $ NINFO( 2 ) = NINFO( 2 ) + 1 | |||
| XNRM = CLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = CONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = CONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL CGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE3*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL CGEMM( 'N', TRANB, M, N, N, | |||
| $ REAL( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, CONE, CC, MAXM ) | |||
| RES1 = CLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( ABS( RMUL )*TNRM )*EPS )*XNRM ) | |||
| * Verify that TRSYL3 only flushes if TRSYL flushes (but | |||
| * there may be cases where TRSYL3 avoid flushing). | |||
| IF( SCALE3.EQ.ZERO .AND. SCALE.GT.ZERO .OR. | |||
| $ IINFO.NE.INFO ) THEN | |||
| NFAIL( 3 ) = NFAIL( 3 ) + 1 | |||
| END IF | |||
| IF( RES.GT.THRESH .OR. SISNAN( RES ) ) | |||
| $ NFAIL( 2 ) = NFAIL( 2 ) + 1 | |||
| IF( RES.GT.RMAX( 2 ) ) | |||
| $ RMAX( 2 ) = RES | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CSYL01 | |||
| * | |||
| END | |||
| @@ -90,21 +90,23 @@ | |||
| LOGICAL OK | |||
| CHARACTER*3 PATH | |||
| INTEGER KLAEXC, KLALN2, KLANV2, KLAQTR, KLASY2, KTREXC, | |||
| $ KTRSEN, KTRSNA, KTRSYL, LLAEXC, LLALN2, LLANV2, | |||
| $ LLAQTR, LLASY2, LTREXC, LTRSYL, NLANV2, NLAQTR, | |||
| $ NLASY2, NTESTS, NTRSYL, KTGEXC, NTGEXC, LTGEXC | |||
| $ KTRSEN, KTRSNA, KTRSYL, KTRSYL3, LLAEXC, | |||
| $ LLALN2, LLANV2, LLAQTR, LLASY2, LTREXC, LTRSYL, | |||
| $ NLANV2, NLAQTR, NLASY2, NTESTS, NTRSYL, KTGEXC, | |||
| $ LTGEXC | |||
| DOUBLE PRECISION EPS, RLAEXC, RLALN2, RLANV2, RLAQTR, RLASY2, | |||
| $ RTREXC, RTRSYL, SFMIN, RTGEXC | |||
| $ RTREXC, SFMIN, RTGEXC | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER LTRSEN( 3 ), LTRSNA( 3 ), NLAEXC( 2 ), | |||
| $ NLALN2( 2 ), NTREXC( 3 ), NTRSEN( 3 ), | |||
| INTEGER FTRSYL( 3 ), ITRSYL( 2 ), LTRSEN( 3 ), | |||
| $ LTRSNA( 3 ), NLAEXC( 2 ), NLALN2( 2 ), | |||
| $ NTGEXC( 2 ), NTREXC( 3 ), NTRSEN( 3 ), | |||
| $ NTRSNA( 3 ) | |||
| DOUBLE PRECISION RTRSEN( 3 ), RTRSNA( 3 ) | |||
| DOUBLE PRECISION RTRSEN( 3 ), RTRSNA( 3 ), RTRSYL( 2 ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DERREC, DGET31, DGET32, DGET33, DGET34, DGET35, | |||
| $ DGET36, DGET37, DGET38, DGET39, DGET40 | |||
| $ DGET36, DGET37, DGET38, DGET39, DGET40, DSYL01 | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DLAMCH | |||
| @@ -153,10 +155,24 @@ | |||
| WRITE( NOUT, FMT = 9996 )RLAEXC, LLAEXC, NLAEXC, KLAEXC | |||
| END IF | |||
| * | |||
| CALL DGET35( RTRSYL, LTRSYL, NTRSYL, KTRSYL ) | |||
| IF( RTRSYL.GT.THRESH ) THEN | |||
| CALL DGET35( RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL ) | |||
| IF( RTRSYL( 1 ).GT.THRESH ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9995 )RTRSYL, LTRSYL, NTRSYL, KTRSYL | |||
| WRITE( NOUT, FMT = 9995 )RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL | |||
| END IF | |||
| * | |||
| CALL DSYL01( THRESH, FTRSYL, RTRSYL, ITRSYL, KTRSYL3 ) | |||
| IF( FTRSYL( 1 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9970 )FTRSYL( 1 ), RTRSYL( 1 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 2 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9971 )FTRSYL( 2 ), RTRSYL( 2 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 3 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9972 )FTRSYL( 3 ) | |||
| END IF | |||
| * | |||
| CALL DGET36( RTREXC, LTREXC, NTREXC, KTREXC, NIN ) | |||
| @@ -227,7 +243,13 @@ | |||
| 9987 FORMAT( ' Routines pass computational tests if test ratio is les', | |||
| $ 's than', F8.2, / / ) | |||
| 9986 FORMAT( ' Error in DTGEXC: RMAX =', D12.3, / ' LMAX = ', I8, ' N', | |||
| $ 'INFO=', I8, ' KNT=', I8 ) | |||
| $ 'INFO=', 2I8, ' KNT=', I8 ) | |||
| 9972 FORMAT( 'DTRSYL and DTRSYL3 compute an inconsistent result ', | |||
| $ 'factor in ', I8, ' tests.') | |||
| 9971 FORMAT( 'Error in DTRSYL3: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| 9970 FORMAT( 'Error in DTRSYL: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| * | |||
| * End of DCHKEC | |||
| * | |||
| @@ -23,7 +23,7 @@ | |||
| *> | |||
| *> DERREC tests the error exits for the routines for eigen- condition | |||
| *> estimation for DOUBLE PRECISION matrices: | |||
| *> DTRSYL, DTREXC, DTRSNA and DTRSEN. | |||
| *> DTRSYL, DTRSYL3, DTREXC, DTRSNA and DTRSEN. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -82,7 +82,7 @@ | |||
| $ WI( NMAX ), WORK( NMAX ), WR( NMAX ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CHKXER, DTREXC, DTRSEN, DTRSNA, DTRSYL | |||
| EXTERNAL CHKXER, DTREXC, DTRSEN, DTRSNA, DTRSYL, DTRSYL3 | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -141,6 +141,43 @@ | |||
| CALL CHKXER( 'DTRSYL', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test DTRSYL3 | |||
| * | |||
| SRNAMT = 'DTRSYL3' | |||
| INFOT = 1 | |||
| CALL DTRSYL3( 'X', 'N', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL DTRSYL3( 'N', 'X', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL DTRSYL3( 'N', 'N', 0, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL DTRSYL3( 'N', 'N', 1, -1, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL DTRSYL3( 'N', 'N', 1, 0, -1, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 7 | |||
| CALL DTRSYL3( 'N', 'N', 1, 2, 0, A, 1, B, 1, C, 2, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 9 | |||
| CALL DTRSYL3( 'N', 'N', 1, 0, 2, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 11 | |||
| CALL DTRSYL3( 'N', 'N', 1, 2, 0, A, 2, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'DTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test DTREXC | |||
| * | |||
| SRNAMT = 'DTREXC' | |||
| @@ -0,0 +1,288 @@ | |||
| *> \brief \b DSYL01 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER KNT | |||
| * DOUBLE PRECISION THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| * DOUBLE PRECISION RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYL01 tests DTRSYL and DTRSYL3, routines for solving the Sylvester matrix | |||
| *> equation | |||
| *> | |||
| *> op(A)*X + ISGN*X*op(B) = scale*C, | |||
| *> | |||
| *> A and B are assumed to be in Schur canonical form, op() represents an | |||
| *> optional transpose, and ISGN can be -1 or +1. Scale is an output | |||
| *> less than or equal to 1, chosen to avoid overflow in X. | |||
| *> | |||
| *> The test code verifies that the following residual does not exceed | |||
| *> the provided threshold: | |||
| *> | |||
| *> norm(op(A)*X + ISGN*X*op(B) - scale*C) / | |||
| *> (EPS*max(norm(A),norm(B))*norm(X)) | |||
| *> | |||
| *> This routine complements DGET35 by testing with larger, | |||
| *> random matrices, of which some require rescaling of X to avoid overflow. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] THRESH | |||
| *> \verbatim | |||
| *> THRESH is DOUBLE PRECISION | |||
| *> A test will count as "failed" if the residual, computed as | |||
| *> described above, exceeds THRESH. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NFAIL | |||
| *> \verbatim | |||
| *> NFAIL is INTEGER array, dimension (3) | |||
| *> NFAIL(1) = No. of times residual DTRSYL exceeds threshold THRESH | |||
| *> NFAIL(2) = No. of times residual DTRSYL3 exceeds threshold THRESH | |||
| *> NFAIL(3) = No. of times DTRSYL3 and DTRSYL deviate | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RMAX | |||
| *> \verbatim | |||
| *> RMAX is DOUBLE PRECISION, dimension (2) | |||
| *> RMAX(1) = Value of the largest test ratio of DTRSYL | |||
| *> RMAX(2) = Value of the largest test ratio of DTRSYL3 | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NINFO | |||
| *> \verbatim | |||
| *> NINFO is INTEGER array, dimension (2) | |||
| *> NINFO(1) = No. of times DTRSYL returns an expected INFO | |||
| *> NINFO(2) = No. of times DTRSYL3 returns an expected INFO | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] KNT | |||
| *> \verbatim | |||
| *> KNT is INTEGER | |||
| *> Total number of examples tested. | |||
| *> \endverbatim | |||
| * | |||
| * -- LAPACK test routine -- | |||
| SUBROUTINE DSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| IMPLICIT NONE | |||
| * | |||
| * -- LAPACK test routine -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER KNT | |||
| DOUBLE PRECISION THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| DOUBLE PRECISION RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * .. | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) | |||
| INTEGER MAXM, MAXN, LDSWORK | |||
| PARAMETER ( MAXM = 245, MAXN = 192, LDSWORK = 36 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| CHARACTER TRANA, TRANB | |||
| INTEGER I, INFO, IINFO, ISGN, ITRANA, ITRANB, J, KLA, | |||
| $ KUA, KLB, KUB, LIWORK, M, N | |||
| DOUBLE PRECISION ANRM, BNRM, BIGNUM, EPS, RES, RES1, RMUL, | |||
| $ SCALE, SCALE3, SMLNUM, TNRM, XNRM | |||
| * .. | |||
| * .. Local Arrays .. | |||
| DOUBLE PRECISION A( MAXM, MAXM ), B( MAXN, MAXN ), | |||
| $ C( MAXM, MAXN ), CC( MAXM, MAXN ), | |||
| $ X( MAXM, MAXN ), | |||
| $ DUML( MAXM ), DUMR( MAXN ), | |||
| $ D( MAX( MAXM, MAXN ) ), DUM( MAXN ), | |||
| $ SWORK( LDSWORK, 126 ), VM( 2 ) | |||
| INTEGER ISEED( 4 ), IWORK( MAXM + MAXN + 2 ), IDUM( 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL DISNAN | |||
| DOUBLE PRECISION DLAMCH, DLANGE | |||
| EXTERNAL DLAMCH, DLANGE | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLATMR, DLACPY, DGEMM, DTRSYL, DTRSYL3 | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, DBLE, MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Get machine parameters | |||
| * | |||
| EPS = DLAMCH( 'P' ) | |||
| SMLNUM = DLAMCH( 'S' ) / EPS | |||
| BIGNUM = ONE / SMLNUM | |||
| * | |||
| VM( 1 ) = ONE | |||
| VM( 2 ) = 0.000001D+0 | |||
| * | |||
| * Begin test loop | |||
| * | |||
| NINFO( 1 ) = 0 | |||
| NINFO( 2 ) = 0 | |||
| NFAIL( 1 ) = 0 | |||
| NFAIL( 2 ) = 0 | |||
| NFAIL( 3 ) = 0 | |||
| RMAX( 1 ) = ZERO | |||
| RMAX( 2 ) = ZERO | |||
| KNT = 0 | |||
| DO I = 1, 4 | |||
| ISEED( I ) = 1 | |||
| END DO | |||
| SCALE = ONE | |||
| SCALE3 = ONE | |||
| LIWORK = MAXM + MAXN + 2 | |||
| DO J = 1, 2 | |||
| DO ISGN = -1, 1, 2 | |||
| * Reset seed (overwritten by LATMR) | |||
| DO I = 1, 4 | |||
| ISEED( I ) = 1 | |||
| END DO | |||
| DO M = 32, MAXM, 71 | |||
| KLA = 0 | |||
| KUA = M - 1 | |||
| CALL DLATMR( M, M, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, ONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLA, KUA, ZERO, | |||
| $ ONE, 'NO', A, MAXM, IWORK, IINFO ) | |||
| DO I = 1, M | |||
| A( I, I ) = A( I, I ) * VM( J ) | |||
| END DO | |||
| ANRM = DLANGE( 'M', M, M, A, MAXM, DUM ) | |||
| DO N = 51, MAXN, 47 | |||
| KLB = 0 | |||
| KUB = N - 1 | |||
| CALL DLATMR( N, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, ONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLB, KUB, ZERO, | |||
| $ ONE, 'NO', B, MAXN, IWORK, IINFO ) | |||
| BNRM = DLANGE( 'M', N, N, B, MAXN, DUM ) | |||
| TNRM = MAX( ANRM, BNRM ) | |||
| CALL DLATMR( M, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, ONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, M, N, ZERO, ONE, | |||
| $ 'NO', C, MAXM, IWORK, IINFO ) | |||
| DO ITRANA = 1, 2 | |||
| IF( ITRANA.EQ.1 ) THEN | |||
| TRANA = 'N' | |||
| END IF | |||
| IF( ITRANA.EQ.2 ) THEN | |||
| TRANA = 'T' | |||
| END IF | |||
| DO ITRANB = 1, 2 | |||
| IF( ITRANB.EQ.1 ) THEN | |||
| TRANB = 'N' | |||
| END IF | |||
| IF( ITRANB.EQ.2 ) THEN | |||
| TRANB = 'T' | |||
| END IF | |||
| KNT = KNT + 1 | |||
| * | |||
| CALL DLACPY( 'All', M, N, C, MAXM, X, MAXM) | |||
| CALL DLACPY( 'All', M, N, C, MAXM, CC, MAXM) | |||
| CALL DTRSYL( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE, IINFO ) | |||
| IF( IINFO.NE.0 ) | |||
| $ NINFO( 1 ) = NINFO( 1 ) + 1 | |||
| XNRM = DLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = ONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = ONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL DGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL DGEMM( 'N', TRANB, M, N, N, | |||
| $ DBLE( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, ONE, CC, MAXM ) | |||
| RES1 = DLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( RMUL*TNRM )*EPS )*XNRM ) | |||
| IF( RES.GT.THRESH ) | |||
| $ NFAIL( 1 ) = NFAIL( 1 ) + 1 | |||
| IF( RES.GT.RMAX( 1 ) ) | |||
| $ RMAX( 1 ) = RES | |||
| * | |||
| CALL DLACPY( 'All', M, N, C, MAXM, X, MAXM ) | |||
| CALL DLACPY( 'All', M, N, C, MAXM, CC, MAXM ) | |||
| CALL DTRSYL3( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE3, IWORK, LIWORK, | |||
| $ SWORK, LDSWORK, INFO) | |||
| IF( INFO.NE.0 ) | |||
| $ NINFO( 2 ) = NINFO( 2 ) + 1 | |||
| XNRM = DLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = ONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = ONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL DGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE3*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL DGEMM( 'N', TRANB, M, N, N, | |||
| $ DBLE( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, ONE, CC, MAXM ) | |||
| RES1 = DLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( RMUL*TNRM )*EPS )*XNRM ) | |||
| * Verify that TRSYL3 only flushes if TRSYL flushes (but | |||
| * there may be cases where TRSYL3 avoid flushing). | |||
| IF( SCALE3.EQ.ZERO .AND. SCALE.GT.ZERO .OR. | |||
| $ IINFO.NE.INFO ) THEN | |||
| NFAIL( 3 ) = NFAIL( 3 ) + 1 | |||
| END IF | |||
| IF( RES.GT.THRESH .OR. DISNAN( RES ) ) | |||
| $ NFAIL( 2 ) = NFAIL( 2 ) + 1 | |||
| IF( RES.GT.RMAX( 2 ) ) | |||
| $ RMAX( 2 ) = RES | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DSYL01 | |||
| * | |||
| END | |||
| @@ -90,21 +90,23 @@ | |||
| LOGICAL OK | |||
| CHARACTER*3 PATH | |||
| INTEGER KLAEXC, KLALN2, KLANV2, KLAQTR, KLASY2, KTREXC, | |||
| $ KTRSEN, KTRSNA, KTRSYL, LLAEXC, LLALN2, LLANV2, | |||
| $ LLAQTR, LLASY2, LTREXC, LTRSYL, NLANV2, NLAQTR, | |||
| $ NLASY2, NTESTS, NTRSYL, KTGEXC, NTGEXC, LTGEXC | |||
| $ KTRSEN, KTRSNA, KTRSYL, KTRSYL3, LLAEXC, | |||
| $ LLALN2, LLANV2, LLAQTR, LLASY2, LTREXC, LTRSYL, | |||
| $ NLANV2, NLAQTR, NLASY2, NTESTS, NTRSYL, KTGEXC, | |||
| $ LTGEXC | |||
| REAL EPS, RLAEXC, RLALN2, RLANV2, RLAQTR, RLASY2, | |||
| $ RTREXC, RTRSYL, SFMIN, RTGEXC | |||
| $ RTREXC, SFMIN, RTGEXC | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER LTRSEN( 3 ), LTRSNA( 3 ), NLAEXC( 2 ), | |||
| $ NLALN2( 2 ), NTREXC( 3 ), NTRSEN( 3 ), | |||
| INTEGER FTRSYL( 3 ), ITRSYL( 2 ), LTRSEN( 3 ), | |||
| $ LTRSNA( 3 ), NLAEXC( 2 ), NLALN2( 2 ), | |||
| $ NTGEXC( 2 ), NTREXC( 3 ), NTRSEN( 3 ), | |||
| $ NTRSNA( 3 ) | |||
| REAL RTRSEN( 3 ), RTRSNA( 3 ) | |||
| REAL RTRSEN( 3 ), RTRSNA( 3 ), RTRSYL( 2 ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL SERREC, SGET31, SGET32, SGET33, SGET34, SGET35, | |||
| $ SGET36, SGET37, SGET38, SGET39, SGET40 | |||
| $ SGET36, SGET37, SGET38, SGET39, SGET40, SSYL01 | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SLAMCH | |||
| @@ -153,10 +155,24 @@ | |||
| WRITE( NOUT, FMT = 9996 )RLAEXC, LLAEXC, NLAEXC, KLAEXC | |||
| END IF | |||
| * | |||
| CALL SGET35( RTRSYL, LTRSYL, NTRSYL, KTRSYL ) | |||
| IF( RTRSYL.GT.THRESH ) THEN | |||
| CALL SGET35( RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL ) | |||
| IF( RTRSYL( 1 ).GT.THRESH ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9995 )RTRSYL, LTRSYL, NTRSYL, KTRSYL | |||
| WRITE( NOUT, FMT = 9995 )RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL | |||
| END IF | |||
| * | |||
| CALL SSYL01( THRESH, FTRSYL, RTRSYL, ITRSYL, KTRSYL3 ) | |||
| IF( FTRSYL( 1 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9970 )FTRSYL( 1 ), RTRSYL( 1 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 2 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9971 )FTRSYL( 2 ), RTRSYL( 2 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 3 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9972 )FTRSYL( 3 ) | |||
| END IF | |||
| * | |||
| CALL SGET36( RTREXC, LTREXC, NTREXC, KTREXC, NIN ) | |||
| @@ -227,7 +243,13 @@ | |||
| 9987 FORMAT( ' Routines pass computational tests if test ratio is les', | |||
| $ 's than', F8.2, / / ) | |||
| 9986 FORMAT( ' Error in STGEXC: RMAX =', E12.3, / ' LMAX = ', I8, ' N', | |||
| $ 'INFO=', I8, ' KNT=', I8 ) | |||
| $ 'INFO=', 2I8, ' KNT=', I8 ) | |||
| 9972 FORMAT( 'STRSYL and STRSYL3 compute an inconsistent result ', | |||
| $ 'factor in ', I8, ' tests.') | |||
| 9971 FORMAT( 'Error in STRSYL3: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| 9970 FORMAT( 'Error in STRSYL: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| * | |||
| * End of SCHKEC | |||
| * | |||
| @@ -23,7 +23,7 @@ | |||
| *> | |||
| *> SERREC tests the error exits for the routines for eigen- condition | |||
| *> estimation for REAL matrices: | |||
| *> STRSYL, STREXC, STRSNA and STRSEN. | |||
| *> STRSYL, STRSYL3, STREXC, STRSNA and STRSEN. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -82,7 +82,7 @@ | |||
| $ WI( NMAX ), WORK( NMAX ), WR( NMAX ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CHKXER, STREXC, STRSEN, STRSNA, STRSYL | |||
| EXTERNAL CHKXER, STREXC, STRSEN, STRSNA, STRSYL, STRSYL3 | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -141,6 +141,43 @@ | |||
| CALL CHKXER( 'STRSYL', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test STRSYL3 | |||
| * | |||
| SRNAMT = 'STRSYL3' | |||
| INFOT = 1 | |||
| CALL STRSYL3( 'X', 'N', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL STRSYL3( 'N', 'X', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL STRSYL3( 'N', 'N', 0, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL STRSYL3( 'N', 'N', 1, -1, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL STRSYL3( 'N', 'N', 1, 0, -1, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 7 | |||
| CALL STRSYL3( 'N', 'N', 1, 2, 0, A, 1, B, 1, C, 2, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 9 | |||
| CALL STRSYL3( 'N', 'N', 1, 0, 2, A, 1, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 11 | |||
| CALL STRSYL3( 'N', 'N', 1, 2, 0, A, 2, B, 1, C, 1, SCALE, | |||
| $ IWORK, NMAX, WORK, NMAX, INFO ) | |||
| CALL CHKXER( 'STRSYL3', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test STREXC | |||
| * | |||
| SRNAMT = 'STREXC' | |||
| @@ -0,0 +1,288 @@ | |||
| *> \brief \b SSYL01 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE SSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER KNT | |||
| * REAL THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| * REAL RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> SSYL01 tests STRSYL and STRSYL3, routines for solving the Sylvester matrix | |||
| *> equation | |||
| *> | |||
| *> op(A)*X + ISGN*X*op(B) = scale*C, | |||
| *> | |||
| *> A and B are assumed to be in Schur canonical form, op() represents an | |||
| *> optional transpose, and ISGN can be -1 or +1. Scale is an output | |||
| *> less than or equal to 1, chosen to avoid overflow in X. | |||
| *> | |||
| *> The test code verifies that the following residual does not exceed | |||
| *> the provided threshold: | |||
| *> | |||
| *> norm(op(A)*X + ISGN*X*op(B) - scale*C) / | |||
| *> (EPS*max(norm(A),norm(B))*norm(X)) | |||
| *> | |||
| *> This routine complements SGET35 by testing with larger, | |||
| *> random matrices, of which some require rescaling of X to avoid overflow. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] THRESH | |||
| *> \verbatim | |||
| *> THRESH is REAL | |||
| *> A test will count as "failed" if the residual, computed as | |||
| *> described above, exceeds THRESH. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NFAIL | |||
| *> \verbatim | |||
| *> NFAIL is INTEGER array, dimension (3) | |||
| *> NFAIL(1) = No. of times residual STRSYL exceeds threshold THRESH | |||
| *> NFAIL(2) = No. of times residual STRSYL3 exceeds threshold THRESH | |||
| *> NFAIL(3) = No. of times STRSYL3 and STRSYL deviate | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RMAX | |||
| *> \verbatim | |||
| *> RMAX is REAL, dimension (2) | |||
| *> RMAX(1) = Value of the largest test ratio of STRSYL | |||
| *> RMAX(2) = Value of the largest test ratio of STRSYL3 | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NINFO | |||
| *> \verbatim | |||
| *> NINFO is INTEGER array, dimension (2) | |||
| *> NINFO(1) = No. of times STRSYL returns an expected INFO | |||
| *> NINFO(2) = No. of times STRSYL3 returns an expected INFO | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] KNT | |||
| *> \verbatim | |||
| *> KNT is INTEGER | |||
| *> Total number of examples tested. | |||
| *> \endverbatim | |||
| * | |||
| * -- LAPACK test routine -- | |||
| SUBROUTINE SSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| IMPLICIT NONE | |||
| * | |||
| * -- LAPACK test routine -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER KNT | |||
| REAL THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| REAL RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * .. | |||
| * .. Parameters .. | |||
| REAL ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| INTEGER MAXM, MAXN, LDSWORK | |||
| PARAMETER ( MAXM = 101, MAXN = 138, LDSWORK = 18 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| CHARACTER TRANA, TRANB | |||
| INTEGER I, INFO, IINFO, ISGN, ITRANA, ITRANB, J, KLA, | |||
| $ KUA, KLB, KUB, LIWORK, M, N | |||
| REAL ANRM, BNRM, BIGNUM, EPS, RES, RES1, RMUL, | |||
| $ SCALE, SCALE3, SMLNUM, TNRM, XNRM | |||
| * .. | |||
| * .. Local Arrays .. | |||
| REAL A( MAXM, MAXM ), B( MAXN, MAXN ), | |||
| $ C( MAXM, MAXN ), CC( MAXM, MAXN ), | |||
| $ X( MAXM, MAXN ), | |||
| $ DUML( MAXM ), DUMR( MAXN ), | |||
| $ D( MAX( MAXM, MAXN ) ), DUM( MAXN ), | |||
| $ SWORK( LDSWORK, 54 ), VM( 2 ) | |||
| INTEGER ISEED( 4 ), IWORK( MAXM + MAXN + 2 ), IDUM( 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL SISNAN | |||
| REAL SLAMCH, SLANGE | |||
| EXTERNAL SISNAN, SLAMCH, SLANGE | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL SLATMR, SLACPY, SGEMM, STRSYL, STRSYL3 | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, REAL, MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Get machine parameters | |||
| * | |||
| EPS = SLAMCH( 'P' ) | |||
| SMLNUM = SLAMCH( 'S' ) / EPS | |||
| BIGNUM = ONE / SMLNUM | |||
| * | |||
| VM( 1 ) = ONE | |||
| VM( 2 ) = 0.05E+0 | |||
| * | |||
| * Begin test loop | |||
| * | |||
| NINFO( 1 ) = 0 | |||
| NINFO( 2 ) = 0 | |||
| NFAIL( 1 ) = 0 | |||
| NFAIL( 2 ) = 0 | |||
| NFAIL( 3 ) = 0 | |||
| RMAX( 1 ) = ZERO | |||
| RMAX( 2 ) = ZERO | |||
| KNT = 0 | |||
| DO I = 1, 4 | |||
| ISEED( I ) = 1 | |||
| END DO | |||
| SCALE = ONE | |||
| SCALE3 = ONE | |||
| LIWORK = MAXM + MAXN + 2 | |||
| DO J = 1, 2 | |||
| DO ISGN = -1, 1, 2 | |||
| * Reset seed (overwritten by LATMR) | |||
| DO I = 1, 4 | |||
| ISEED( I ) = 1 | |||
| END DO | |||
| DO M = 32, MAXM, 71 | |||
| KLA = 0 | |||
| KUA = M - 1 | |||
| CALL SLATMR( M, M, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, ONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLA, KUA, ZERO, | |||
| $ ONE, 'NO', A, MAXM, IWORK, IINFO ) | |||
| DO I = 1, M | |||
| A( I, I ) = A( I, I ) * VM( J ) | |||
| END DO | |||
| ANRM = SLANGE( 'M', M, M, A, MAXM, DUM ) | |||
| DO N = 51, MAXN, 47 | |||
| KLB = 0 | |||
| KUB = N - 1 | |||
| CALL SLATMR( N, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, ONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLB, KUB, ZERO, | |||
| $ ONE, 'NO', B, MAXN, IWORK, IINFO ) | |||
| BNRM = SLANGE( 'M', N, N, B, MAXN, DUM ) | |||
| TNRM = MAX( ANRM, BNRM ) | |||
| CALL SLATMR( M, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, ONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, M, N, ZERO, ONE, | |||
| $ 'NO', C, MAXM, IWORK, IINFO ) | |||
| DO ITRANA = 1, 2 | |||
| IF( ITRANA.EQ.1 ) THEN | |||
| TRANA = 'N' | |||
| END IF | |||
| IF( ITRANA.EQ.2 ) THEN | |||
| TRANA = 'T' | |||
| END IF | |||
| DO ITRANB = 1, 2 | |||
| IF( ITRANB.EQ.1 ) THEN | |||
| TRANB = 'N' | |||
| END IF | |||
| IF( ITRANB.EQ.2 ) THEN | |||
| TRANB = 'T' | |||
| END IF | |||
| KNT = KNT + 1 | |||
| * | |||
| CALL SLACPY( 'All', M, N, C, MAXM, X, MAXM) | |||
| CALL SLACPY( 'All', M, N, C, MAXM, CC, MAXM) | |||
| CALL STRSYL( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE, IINFO ) | |||
| IF( IINFO.NE.0 ) | |||
| $ NINFO( 1 ) = NINFO( 1 ) + 1 | |||
| XNRM = SLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = ONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = ONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL SGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE*RMUL, | |||
| $ C, MAXM ) | |||
| CALL SGEMM( 'N', TRANB, M, N, N, | |||
| $ REAL( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, ONE, C, MAXM ) | |||
| RES1 = SLANGE( 'M', M, N, C, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( RMUL*TNRM )*EPS )*XNRM ) | |||
| IF( RES.GT.THRESH ) | |||
| $ NFAIL( 1 ) = NFAIL( 1 ) + 1 | |||
| IF( RES.GT.RMAX( 1 ) ) | |||
| $ RMAX( 1 ) = RES | |||
| * | |||
| CALL SLACPY( 'All', M, N, C, MAXM, X, MAXM ) | |||
| CALL SLACPY( 'All', M, N, C, MAXM, CC, MAXM ) | |||
| CALL STRSYL3( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE3, IWORK, LIWORK, | |||
| $ SWORK, LDSWORK, INFO) | |||
| IF( INFO.NE.0 ) | |||
| $ NINFO( 2 ) = NINFO( 2 ) + 1 | |||
| XNRM = SLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = ONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = ONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL SGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE3*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL SGEMM( 'N', TRANB, M, N, N, | |||
| $ REAL( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, ONE, CC, MAXM ) | |||
| RES1 = SLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( RMUL*TNRM )*EPS )*XNRM ) | |||
| * Verify that TRSYL3 only flushes if TRSYL flushes (but | |||
| * there may be cases where TRSYL3 avoid flushing). | |||
| IF( SCALE3.EQ.ZERO .AND. SCALE.GT.ZERO .OR. | |||
| $ IINFO.NE.INFO ) THEN | |||
| NFAIL( 3 ) = NFAIL( 3 ) + 1 | |||
| END IF | |||
| IF( RES.GT.THRESH .OR. SISNAN( RES ) ) | |||
| $ NFAIL( 2 ) = NFAIL( 2 ) + 1 | |||
| IF( RES.GT.RMAX( 2 ) ) | |||
| $ RMAX( 2 ) = RES | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of SSYL01 | |||
| * | |||
| END | |||
| @@ -88,17 +88,17 @@ | |||
| * .. Local Scalars .. | |||
| LOGICAL OK | |||
| CHARACTER*3 PATH | |||
| INTEGER KTREXC, KTRSEN, KTRSNA, KTRSYL, LTREXC, LTRSYL, | |||
| $ NTESTS, NTREXC, NTRSYL | |||
| DOUBLE PRECISION EPS, RTREXC, RTRSYL, SFMIN | |||
| INTEGER KTREXC, KTRSEN, KTRSNA, KTRSYL, KTRSYL3, | |||
| $ LTREXC, LTRSYL, NTESTS, NTREXC, NTRSYL | |||
| DOUBLE PRECISION EPS, RTREXC, SFMIN | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER LTRSEN( 3 ), LTRSNA( 3 ), NTRSEN( 3 ), | |||
| $ NTRSNA( 3 ) | |||
| DOUBLE PRECISION RTRSEN( 3 ), RTRSNA( 3 ) | |||
| INTEGER FTRSYL( 3 ), ITRSYL( 2 ), LTRSEN( 3 ), | |||
| $ LTRSNA( 3 ), NTRSEN( 3 ), NTRSNA( 3 ) | |||
| DOUBLE PRECISION RTRSEN( 3 ), RTRSNA( 3 ), RTRSYL( 2 ) | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ZERREC, ZGET35, ZGET36, ZGET37, ZGET38 | |||
| EXTERNAL ZERREC, ZGET35, ZGET36, ZGET37, ZGET38, ZSYL01 | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DLAMCH | |||
| @@ -120,10 +120,24 @@ | |||
| $ CALL ZERREC( PATH, NOUT ) | |||
| * | |||
| OK = .TRUE. | |||
| CALL ZGET35( RTRSYL, LTRSYL, NTRSYL, KTRSYL, NIN ) | |||
| IF( RTRSYL.GT.THRESH ) THEN | |||
| CALL ZGET35( RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL, NIN ) | |||
| IF( RTRSYL( 1 ).GT.THRESH ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9999 )RTRSYL, LTRSYL, NTRSYL, KTRSYL | |||
| WRITE( NOUT, FMT = 9999 )RTRSYL( 1 ), LTRSYL, NTRSYL, KTRSYL | |||
| END IF | |||
| * | |||
| CALL ZSYL01( THRESH, FTRSYL, RTRSYL, ITRSYL, KTRSYL3 ) | |||
| IF( FTRSYL( 1 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9970 )FTRSYL( 1 ), RTRSYL( 1 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 2 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9971 )FTRSYL( 2 ), RTRSYL( 2 ), THRESH | |||
| END IF | |||
| IF( FTRSYL( 3 ).GT.0 ) THEN | |||
| OK = .FALSE. | |||
| WRITE( NOUT, FMT = 9972 )FTRSYL( 3 ) | |||
| END IF | |||
| * | |||
| CALL ZGET36( RTREXC, LTREXC, NTREXC, KTREXC, NIN ) | |||
| @@ -148,7 +162,7 @@ | |||
| WRITE( NOUT, FMT = 9996 )RTRSEN, LTRSEN, NTRSEN, KTRSEN | |||
| END IF | |||
| * | |||
| NTESTS = KTRSYL + KTREXC + KTRSNA + KTRSEN | |||
| NTESTS = KTRSYL + KTRSYL3 + KTREXC + KTRSNA + KTRSEN | |||
| IF( OK ) | |||
| $ WRITE( NOUT, FMT = 9995 )PATH, NTESTS | |||
| * | |||
| @@ -169,6 +183,12 @@ | |||
| $ / ' Safe minimum (SFMIN) = ', D16.6, / ) | |||
| 9992 FORMAT( ' Routines pass computational tests if test ratio is ', | |||
| $ 'less than', F8.2, / / ) | |||
| 9970 FORMAT( 'Error in ZTRSYL: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| 9971 FORMAT( 'Error in ZTRSYL3: ', I8, ' tests fail the threshold.', / | |||
| $ 'Maximum test ratio =', D12.3, ' threshold =', D12.3 ) | |||
| 9972 FORMAT( 'ZTRSYL and ZTRSYL3 compute an inconsistent scale ', | |||
| $ 'factor in ', I8, ' tests.') | |||
| RETURN | |||
| * | |||
| * End of ZCHKEC | |||
| @@ -23,7 +23,7 @@ | |||
| *> | |||
| *> ZERREC tests the error exits for the routines for eigen- condition | |||
| *> estimation for DOUBLE PRECISION matrices: | |||
| *> ZTRSYL, ZTREXC, ZTRSNA and ZTRSEN. | |||
| *> ZTRSYL, ZTRSYL3, ZTREXC, ZTRSNA and ZTRSEN. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -77,7 +77,7 @@ | |||
| * .. | |||
| * .. Local Arrays .. | |||
| LOGICAL SEL( NMAX ) | |||
| DOUBLE PRECISION RW( LW ), S( NMAX ), SEP( NMAX ) | |||
| DOUBLE PRECISION RW( LW ), S( NMAX ), SEP( NMAX ), SWORK( NMAX ) | |||
| COMPLEX*16 A( NMAX, NMAX ), B( NMAX, NMAX ), | |||
| $ C( NMAX, NMAX ), WORK( LW ), X( NMAX ) | |||
| * .. | |||
| @@ -141,6 +141,43 @@ | |||
| CALL CHKXER( 'ZTRSYL', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test ZTRSYL3 | |||
| * | |||
| SRNAMT = 'ZTRSYL3' | |||
| INFOT = 1 | |||
| CALL ZTRSYL3( 'X', 'N', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL ZTRSYL3( 'N', 'X', 1, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL ZTRSYL3( 'N', 'N', 0, 0, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL ZTRSYL3( 'N', 'N', 1, -1, 0, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL ZTRSYL3( 'N', 'N', 1, 0, -1, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 7 | |||
| CALL ZTRSYL3( 'N', 'N', 1, 2, 0, A, 1, B, 1, C, 2, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 9 | |||
| CALL ZTRSYL3( 'N', 'N', 1, 0, 2, A, 1, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 11 | |||
| CALL ZTRSYL3( 'N', 'N', 1, 2, 0, A, 2, B, 1, C, 1, SCALE, | |||
| $ SWORK, NMAX, INFO ) | |||
| CALL CHKXER( 'ZTRSYL3', INFOT, NOUT, LERR, OK ) | |||
| NT = NT + 8 | |||
| * | |||
| * Test ZTREXC | |||
| * | |||
| SRNAMT = 'ZTREXC' | |||
| @@ -0,0 +1,294 @@ | |||
| *> \brief \b ZSYL01 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE ZSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER KNT | |||
| * DOUBLE PRECISION THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| * DOUBLE PRECISION RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> ZSYL01 tests ZTRSYL and ZTRSYL3, routines for solving the Sylvester matrix | |||
| *> equation | |||
| *> | |||
| *> op(A)*X + ISGN*X*op(B) = scale*C, | |||
| *> | |||
| *> where op(A) and op(B) are both upper triangular form, op() represents an | |||
| *> optional conjugate transpose, and ISGN can be -1 or +1. Scale is an output | |||
| *> less than or equal to 1, chosen to avoid overflow in X. | |||
| *> | |||
| *> The test code verifies that the following residual does not exceed | |||
| *> the provided threshold: | |||
| *> | |||
| *> norm(op(A)*X + ISGN*X*op(B) - scale*C) / | |||
| *> (EPS*max(norm(A),norm(B))*norm(X)) | |||
| *> | |||
| *> This routine complements ZGET35 by testing with larger, | |||
| *> random matrices, of which some require rescaling of X to avoid overflow. | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] THRESH | |||
| *> \verbatim | |||
| *> THRESH is DOUBLE PRECISION | |||
| *> A test will count as "failed" if the residual, computed as | |||
| *> described above, exceeds THRESH. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NFAIL | |||
| *> \verbatim | |||
| *> NFAIL is INTEGER array, dimension (3) | |||
| *> NFAIL(1) = No. of times residual ZTRSYL exceeds threshold THRESH | |||
| *> NFAIL(2) = No. of times residual ZTRSYL3 exceeds threshold THRESH | |||
| *> NFAIL(3) = No. of times ZTRSYL3 and ZTRSYL deviate | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RMAX | |||
| *> \verbatim | |||
| *> RMAX is DOUBLE PRECISION array, dimension (2) | |||
| *> RMAX(1) = Value of the largest test ratio of ZTRSYL | |||
| *> RMAX(2) = Value of the largest test ratio of ZTRSYL3 | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] NINFO | |||
| *> \verbatim | |||
| *> NINFO is INTEGER array, dimension (2) | |||
| *> NINFO(1) = No. of times ZTRSYL returns an expected INFO | |||
| *> NINFO(2) = No. of times ZTRSYL3 returns an expected INFO | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] KNT | |||
| *> \verbatim | |||
| *> KNT is INTEGER | |||
| *> Total number of examples tested. | |||
| *> \endverbatim | |||
| * | |||
| * -- LAPACK test routine -- | |||
| SUBROUTINE ZSYL01( THRESH, NFAIL, RMAX, NINFO, KNT ) | |||
| IMPLICIT NONE | |||
| * | |||
| * -- LAPACK test routine -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER KNT | |||
| DOUBLE PRECISION THRESH | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER NFAIL( 3 ), NINFO( 2 ) | |||
| DOUBLE PRECISION RMAX( 2 ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * .. | |||
| * .. Parameters .. | |||
| COMPLEX*16 CONE | |||
| PARAMETER ( CONE = ( 1.0D0, 0.0D+0 ) ) | |||
| DOUBLE PRECISION ONE, ZERO | |||
| PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) | |||
| INTEGER MAXM, MAXN, LDSWORK | |||
| PARAMETER ( MAXM = 185, MAXN = 192, LDSWORK = 36 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| CHARACTER TRANA, TRANB | |||
| INTEGER I, INFO, IINFO, ISGN, ITRANA, ITRANB, J, KLA, | |||
| $ KUA, KLB, KUB, M, N | |||
| DOUBLE PRECISION ANRM, BNRM, BIGNUM, EPS, RES, RES1, | |||
| $ SCALE, SCALE3, SMLNUM, TNRM, XNRM | |||
| COMPLEX*16 RMUL | |||
| * .. | |||
| * .. Local Arrays .. | |||
| COMPLEX*16 A( MAXM, MAXM ), B( MAXN, MAXN ), | |||
| $ C( MAXM, MAXN ), CC( MAXM, MAXN ), | |||
| $ X( MAXM, MAXN ), | |||
| $ DUML( MAXM ), DUMR( MAXN ), | |||
| $ D( MIN( MAXM, MAXN ) ) | |||
| DOUBLE PRECISION SWORK( LDSWORK, 103 ), DUM( MAXN ), VM( 2 ) | |||
| INTEGER ISEED( 4 ), IWORK( MAXM + MAXN + 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL DISNAN | |||
| DOUBLE PRECISION DLAMCH, ZLANGE | |||
| EXTERNAL DISNAN, DLAMCH, ZLANGE | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ZLATMR, ZLACPY, ZGEMM, ZTRSYL, ZTRSYL3 | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, DBLE, MAX, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Get machine parameters | |||
| * | |||
| EPS = DLAMCH( 'P' ) | |||
| SMLNUM = DLAMCH( 'S' ) / EPS | |||
| BIGNUM = ONE / SMLNUM | |||
| * | |||
| * Expect INFO = 0 | |||
| VM( 1 ) = ONE | |||
| * Expect INFO = 1 | |||
| VM( 2 ) = 0.05D+0 | |||
| * | |||
| * Begin test loop | |||
| * | |||
| NINFO( 1 ) = 0 | |||
| NINFO( 2 ) = 0 | |||
| NFAIL( 1 ) = 0 | |||
| NFAIL( 2 ) = 0 | |||
| NFAIL( 3 ) = 0 | |||
| RMAX( 1 ) = ZERO | |||
| RMAX( 2 ) = ZERO | |||
| KNT = 0 | |||
| ISEED( 1 ) = 1 | |||
| ISEED( 2 ) = 1 | |||
| ISEED( 3 ) = 1 | |||
| ISEED( 4 ) = 1 | |||
| SCALE = ONE | |||
| SCALE3 = ONE | |||
| DO J = 1, 2 | |||
| DO ISGN = -1, 1, 2 | |||
| * Reset seed (overwritten by LATMR) | |||
| ISEED( 1 ) = 1 | |||
| ISEED( 2 ) = 1 | |||
| ISEED( 3 ) = 1 | |||
| ISEED( 4 ) = 1 | |||
| DO M = 32, MAXM, 51 | |||
| KLA = 0 | |||
| KUA = M - 1 | |||
| CALL ZLATMR( M, M, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, CONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLA, KUA, ZERO, | |||
| $ ONE, 'NO', A, MAXM, IWORK, | |||
| $ IINFO ) | |||
| DO I = 1, M | |||
| A( I, I ) = A( I, I ) * VM( J ) | |||
| END DO | |||
| ANRM = ZLANGE( 'M', M, M, A, MAXM, DUM ) | |||
| DO N = 51, MAXN, 47 | |||
| KLB = 0 | |||
| KUB = N - 1 | |||
| CALL ZLATMR( N, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, CONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, KLB, KUB, ZERO, | |||
| $ ONE, 'NO', B, MAXN, IWORK, | |||
| $ IINFO ) | |||
| DO I = 1, N | |||
| B( I, I ) = B( I, I ) * VM ( J ) | |||
| END DO | |||
| BNRM = ZLANGE( 'M', N, N, B, MAXN, DUM ) | |||
| TNRM = MAX( ANRM, BNRM ) | |||
| CALL ZLATMR( M, N, 'S', ISEED, 'N', D, | |||
| $ 6, ONE, CONE, 'T', 'N', | |||
| $ DUML, 1, ONE, DUMR, 1, ONE, | |||
| $ 'N', IWORK, M, N, ZERO, ONE, | |||
| $ 'NO', C, MAXM, IWORK, IINFO ) | |||
| DO ITRANA = 1, 2 | |||
| IF( ITRANA.EQ.1 ) | |||
| $ TRANA = 'N' | |||
| IF( ITRANA.EQ.2 ) | |||
| $ TRANA = 'C' | |||
| DO ITRANB = 1, 2 | |||
| IF( ITRANB.EQ.1 ) | |||
| $ TRANB = 'N' | |||
| IF( ITRANB.EQ.2 ) | |||
| $ TRANB = 'C' | |||
| KNT = KNT + 1 | |||
| * | |||
| CALL ZLACPY( 'All', M, N, C, MAXM, X, MAXM) | |||
| CALL ZLACPY( 'All', M, N, C, MAXM, CC, MAXM) | |||
| CALL ZTRSYL( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE, IINFO ) | |||
| IF( IINFO.NE.0 ) | |||
| $ NINFO( 1 ) = NINFO( 1 ) + 1 | |||
| XNRM = ZLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = CONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = CONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL ZGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL ZGEMM( 'N', TRANB, M, N, N, | |||
| $ DBLE( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, CONE, CC, MAXM ) | |||
| RES1 = ZLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( ABS( RMUL )*TNRM )*EPS )*XNRM ) | |||
| IF( RES.GT.THRESH ) | |||
| $ NFAIL( 1 ) = NFAIL( 1 ) + 1 | |||
| IF( RES.GT.RMAX( 1 ) ) | |||
| $ RMAX( 1 ) = RES | |||
| * | |||
| CALL ZLACPY( 'All', M, N, C, MAXM, X, MAXM ) | |||
| CALL ZLACPY( 'All', M, N, C, MAXM, CC, MAXM ) | |||
| CALL ZTRSYL3( TRANA, TRANB, ISGN, M, N, | |||
| $ A, MAXM, B, MAXN, X, MAXM, | |||
| $ SCALE3, SWORK, LDSWORK, INFO) | |||
| IF( INFO.NE.0 ) | |||
| $ NINFO( 2 ) = NINFO( 2 ) + 1 | |||
| XNRM = ZLANGE( 'M', M, N, X, MAXM, DUM ) | |||
| RMUL = CONE | |||
| IF( XNRM.GT.ONE .AND. TNRM.GT.ONE ) THEN | |||
| IF( XNRM.GT.BIGNUM / TNRM ) THEN | |||
| RMUL = CONE / MAX( XNRM, TNRM ) | |||
| END IF | |||
| END IF | |||
| CALL ZGEMM( TRANA, 'N', M, N, M, RMUL, | |||
| $ A, MAXM, X, MAXM, -SCALE3*RMUL, | |||
| $ CC, MAXM ) | |||
| CALL ZGEMM( 'N', TRANB, M, N, N, | |||
| $ DBLE( ISGN )*RMUL, X, MAXM, B, | |||
| $ MAXN, CONE, CC, MAXM ) | |||
| RES1 = ZLANGE( 'M', M, N, CC, MAXM, DUM ) | |||
| RES = RES1 / MAX( SMLNUM, SMLNUM*XNRM, | |||
| $ ( ( ABS( RMUL )*TNRM )*EPS )*XNRM ) | |||
| * Verify that TRSYL3 only flushes if TRSYL flushes (but | |||
| * there may be cases where TRSYL3 avoid flushing). | |||
| IF( SCALE3.EQ.ZERO .AND. SCALE.GT.ZERO .OR. | |||
| $ IINFO.NE.INFO ) THEN | |||
| NFAIL( 3 ) = NFAIL( 3 ) + 1 | |||
| END IF | |||
| IF( RES.GT.THRESH .OR. DISNAN( RES ) ) | |||
| $ NFAIL( 2 ) = NFAIL( 2 ) + 1 | |||
| IF( RES.GT.RMAX( 2 ) ) | |||
| $ RMAX( 2 ) = RES | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of ZSYL01 | |||
| * | |||
| END | |||
| @@ -31,7 +31,7 @@ | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CCHKTR tests CTRTRI, -TRS, -RFS, and -CON, and CLATRS | |||
| *> CCHKTR tests CTRTRI, -TRS, -RFS, and -CON, and CLATRS(3) | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -184,7 +184,7 @@ | |||
| INTEGER NTYPE1, NTYPES | |||
| PARAMETER ( NTYPE1 = 10, NTYPES = 18 ) | |||
| INTEGER NTESTS | |||
| PARAMETER ( NTESTS = 9 ) | |||
| PARAMETER ( NTESTS = 10 ) | |||
| INTEGER NTRAN | |||
| PARAMETER ( NTRAN = 3 ) | |||
| REAL ONE, ZERO | |||
| @@ -195,13 +195,13 @@ | |||
| CHARACTER*3 PATH | |||
| INTEGER I, IDIAG, IMAT, IN, INB, INFO, IRHS, ITRAN, | |||
| $ IUPLO, K, LDA, N, NB, NERRS, NFAIL, NRHS, NRUN | |||
| REAL AINVNM, ANORM, DUMMY, RCOND, RCONDC, RCONDI, | |||
| $ RCONDO, SCALE | |||
| REAL AINVNM, ANORM, BIGNUM, DUMMY, RCOND, RCONDC, | |||
| $ RCONDI, RCONDO, RES, SCALE, SLAMCH | |||
| * .. | |||
| * .. Local Arrays .. | |||
| CHARACTER TRANSS( NTRAN ), UPLOS( 2 ) | |||
| INTEGER ISEED( 4 ), ISEEDY( 4 ) | |||
| REAL RESULT( NTESTS ) | |||
| REAL RESULT( NTESTS ), SCALE3( 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| @@ -210,9 +210,9 @@ | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAERH, ALAHD, ALASUM, CCOPY, CERRTR, CGET04, | |||
| $ CLACPY, CLARHS, CLATRS, CLATTR, CTRCON, CTRRFS, | |||
| $ CTRT01, CTRT02, CTRT03, CTRT05, CTRT06, CTRTRI, | |||
| $ CTRTRS, XLAENV | |||
| $ CLACPY, CLARHS, CLATRS, CLATRS3, CLATTR, | |||
| $ CSSCAL, CTRCON, CTRRFS, CTRT01, CTRT02, CTRT03, | |||
| $ CTRT05, CTRT06, CTRTRI, CTRTRS, XLAENV, SLAMCH | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -236,6 +236,7 @@ | |||
| * | |||
| PATH( 1: 1 ) = 'Complex precision' | |||
| PATH( 2: 3 ) = 'TR' | |||
| BIGNUM = SLAMCH('Overflow') / SLAMCH('Precision') | |||
| NRUN = 0 | |||
| NFAIL = 0 | |||
| NERRS = 0 | |||
| @@ -380,7 +381,7 @@ | |||
| * This line is needed on a Sun SPARCstation. | |||
| * | |||
| IF( N.GT.0 ) | |||
| $ DUMMY = A( 1 ) | |||
| $ DUMMY = REAL( A( 1 ) ) | |||
| * | |||
| CALL CTRT02( UPLO, TRANS, DIAG, N, NRHS, A, LDA, | |||
| $ X, LDA, B, LDA, WORK, RWORK, | |||
| @@ -535,6 +536,32 @@ | |||
| $ RWORK, ONE, B( N+1 ), LDA, X, LDA, WORK, | |||
| $ RESULT( 9 ) ) | |||
| * | |||
| *+ TEST 10 | |||
| * Solve op(A)*X = B. | |||
| * | |||
| SRNAMT = 'CLATRS3' | |||
| CALL CCOPY( N, X, 1, B, 1 ) | |||
| CALL CCOPY( N, X, 1, B, 1 ) | |||
| CALL CSCAL( N, BIGNUM, B( N+1 ), 1 ) | |||
| CALL CLATRS3( UPLO, TRANS, DIAG, 'N', N, 2, A, LDA, | |||
| $ B, MAX(1, N), SCALE3, RWORK, WORK, NMAX, | |||
| $ INFO ) | |||
| * | |||
| * Check error code from CLATRS3. | |||
| * | |||
| IF( INFO.NE.0 ) | |||
| $ CALL ALAERH( PATH, 'CLATRS3', INFO, 0, | |||
| $ UPLO // TRANS // DIAG // 'Y', N, N, | |||
| $ -1, -1, -1, IMAT, NFAIL, NERRS, NOUT ) | |||
| CALL CTRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 1 ), RWORK, ONE, B( 1 ), LDA, | |||
| $ X, LDA, WORK, RESULT( 10 ) ) | |||
| CALL CSSCAL( N, BIGNUM, X, 1 ) | |||
| CALL CTRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 2 ), RWORK, ONE, B( N+1 ), LDA, | |||
| $ X, LDA, WORK, RESULT( 10 ) ) | |||
| RESULT( 10 ) = MAX( RESULT( 10 ), RES ) | |||
| * | |||
| * Print information about the tests that did not pass | |||
| * the threshold. | |||
| * | |||
| @@ -552,7 +579,14 @@ | |||
| $ DIAG, 'Y', N, IMAT, 9, RESULT( 9 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 2 | |||
| IF( RESULT( 10 ).GE.THRESH ) THEN | |||
| IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 ) | |||
| $ CALL ALAHD( NOUT, PATH ) | |||
| WRITE( NOUT, FMT = 9996 )'CLATRS3', UPLO, TRANS, | |||
| $ DIAG, 'N', N, IMAT, 10, RESULT( 10 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 3 | |||
| 90 CONTINUE | |||
| 100 CONTINUE | |||
| 110 CONTINUE | |||
| @@ -82,9 +82,10 @@ | |||
| EXTERNAL LSAMEN | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAESM, CHKXER, CLATBS, CLATPS, CLATRS, CTBCON, | |||
| $ CTBRFS, CTBTRS, CTPCON, CTPRFS, CTPTRI, CTPTRS, | |||
| $ CTRCON, CTRRFS, CTRTI2, CTRTRI, CTRTRS | |||
| EXTERNAL ALAESM, CHKXER, CLATBS, CLATPS, CLATRS, | |||
| $ CLATRS3, CTBCON, CTBRFS, CTBTRS, CTPCON, | |||
| $ CTPRFS, CTPTRI, CTPTRS, CTRCON, CTRRFS, CTRTI2, | |||
| $ CTRTRI, CTRTRS | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -240,6 +241,46 @@ | |||
| CALL CLATRS( 'U', 'N', 'N', 'N', 2, A, 1, X, SCALE, RW, INFO ) | |||
| CALL CHKXER( 'CLATRS', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| * CLATRS3 | |||
| * | |||
| SRNAMT = 'CLATRS3' | |||
| INFOT = 1 | |||
| CALL CLATRS3( '/', 'N', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL CLATRS3( 'U', '/', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL CLATRS3( 'U', 'N', '/', 'N', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL CLATRS3( 'U', 'N', 'N', '/', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL CLATRS3( 'U', 'N', 'N', 'N', -1, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 6 | |||
| CALL CLATRS3( 'U', 'N', 'N', 'N', 0, -1, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 8 | |||
| CALL CLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 10 | |||
| CALL CLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 2, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 14 | |||
| CALL CLATRS3( 'U', 'N', 'N', 'N', 1, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 0, INFO ) | |||
| CALL CHKXER( 'CLATRS3', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| * Test error exits for the packed triangular routines. | |||
| * | |||
| ELSE IF( LSAMEN( 2, C2, 'TP' ) ) THEN | |||
| @@ -30,7 +30,7 @@ | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DCHKTR tests DTRTRI, -TRS, -RFS, and -CON, and DLATRS | |||
| *> DCHKTR tests DTRTRI, -TRS, -RFS, and -CON, and DLATRS(3) | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -187,7 +187,7 @@ | |||
| INTEGER NTYPE1, NTYPES | |||
| PARAMETER ( NTYPE1 = 10, NTYPES = 18 ) | |||
| INTEGER NTESTS | |||
| PARAMETER ( NTESTS = 9 ) | |||
| PARAMETER ( NTESTS = 10 ) | |||
| INTEGER NTRAN | |||
| PARAMETER ( NTRAN = 3 ) | |||
| DOUBLE PRECISION ONE, ZERO | |||
| @@ -198,13 +198,13 @@ | |||
| CHARACTER*3 PATH | |||
| INTEGER I, IDIAG, IMAT, IN, INB, INFO, IRHS, ITRAN, | |||
| $ IUPLO, K, LDA, N, NB, NERRS, NFAIL, NRHS, NRUN | |||
| DOUBLE PRECISION AINVNM, ANORM, DUMMY, RCOND, RCONDC, RCONDI, | |||
| $ RCONDO, SCALE | |||
| DOUBLE PRECISION AINVNM, ANORM, BIGNUM, DLAMCH, DUMMY, RCOND, | |||
| $ RCONDC, RCONDI, RCONDO, RES, SCALE | |||
| * .. | |||
| * .. Local Arrays .. | |||
| CHARACTER TRANSS( NTRAN ), UPLOS( 2 ) | |||
| INTEGER ISEED( 4 ), ISEEDY( 4 ) | |||
| DOUBLE PRECISION RESULT( NTESTS ) | |||
| DOUBLE PRECISION RESULT( NTESTS ), SCALE3( 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| @@ -213,9 +213,9 @@ | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAERH, ALAHD, ALASUM, DCOPY, DERRTR, DGET04, | |||
| $ DLACPY, DLARHS, DLATRS, DLATTR, DTRCON, DTRRFS, | |||
| $ DTRT01, DTRT02, DTRT03, DTRT05, DTRT06, DTRTRI, | |||
| $ DTRTRS, XLAENV | |||
| $ DLACPY, DLAMCH, DSCAL, DLARHS, DLATRS, DLATRS3, | |||
| $ DLATTR, DTRCON, DTRRFS, DTRT01, DTRT02, DTRT03, | |||
| $ DTRT05, DTRT06, DTRTRI, DTRTRS, XLAENV | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -239,6 +239,7 @@ | |||
| * | |||
| PATH( 1: 1 ) = 'Double precision' | |||
| PATH( 2: 3 ) = 'TR' | |||
| BIGNUM = DLAMCH('Overflow') / DLAMCH('Precision') | |||
| NRUN = 0 | |||
| NFAIL = 0 | |||
| NERRS = 0 | |||
| @@ -539,6 +540,32 @@ | |||
| $ RWORK, ONE, B( N+1 ), LDA, X, LDA, WORK, | |||
| $ RESULT( 9 ) ) | |||
| * | |||
| *+ TEST 10 | |||
| * Solve op(A)*X = B | |||
| * | |||
| SRNAMT = 'DLATRS3' | |||
| CALL DCOPY( N, X, 1, B, 1 ) | |||
| CALL DCOPY( N, X, 1, B( N+1 ), 1 ) | |||
| CALL DSCAL( N, BIGNUM, B( N+1 ), 1 ) | |||
| CALL DLATRS3( UPLO, TRANS, DIAG, 'N', N, 2, A, LDA, | |||
| $ B, MAX(1, N), SCALE3, RWORK, WORK, NMAX, | |||
| $ INFO ) | |||
| * | |||
| * Check error code from DLATRS3. | |||
| * | |||
| IF( INFO.NE.0 ) | |||
| $ CALL ALAERH( PATH, 'DLATRS3', INFO, 0, | |||
| $ UPLO // TRANS // DIAG // 'N', N, N, | |||
| $ -1, -1, -1, IMAT, NFAIL, NERRS, NOUT ) | |||
| CALL DTRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 1 ), RWORK, ONE, B( 1 ), LDA, | |||
| $ X, LDA, WORK, RESULT( 10 ) ) | |||
| CALL DSCAL( N, BIGNUM, X, 1 ) | |||
| CALL DTRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 2 ), RWORK, ONE, B( N+1 ), LDA, | |||
| $ X, LDA, WORK, RES ) | |||
| RESULT( 10 ) = MAX( RESULT( 10 ), RES ) | |||
| * | |||
| * Print information about the tests that did not pass | |||
| * the threshold. | |||
| * | |||
| @@ -556,7 +583,14 @@ | |||
| $ DIAG, 'Y', N, IMAT, 9, RESULT( 9 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 2 | |||
| IF( RESULT( 10 ).GE.THRESH ) THEN | |||
| IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 ) | |||
| $ CALL ALAHD( NOUT, PATH ) | |||
| WRITE( NOUT, FMT = 9996 )'DLATRS3', UPLO, TRANS, | |||
| $ DIAG, 'N', N, IMAT, 10, RESULT( 10 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 3 | |||
| 90 CONTINUE | |||
| 100 CONTINUE | |||
| 110 CONTINUE | |||
| @@ -569,8 +603,8 @@ | |||
| 9999 FORMAT( ' UPLO=''', A1, ''', DIAG=''', A1, ''', N=', I5, ', NB=', | |||
| $ I4, ', type ', I2, ', test(', I2, ')= ', G12.5 ) | |||
| 9998 FORMAT( ' UPLO=''', A1, ''', TRANS=''', A1, ''', DIAG=''', A1, | |||
| $ ''', N=', I5, ', NB=', I4, ', type ', I2, ', | |||
| $ test(', I2, ')= ', G12.5 ) | |||
| $ ''', N=', I5, ', NB=', I4, ', type ', I2, ', test(', | |||
| $ I2, ')= ', G12.5 ) | |||
| 9997 FORMAT( ' NORM=''', A1, ''', UPLO =''', A1, ''', N=', I5, ',', | |||
| $ 11X, ' type ', I2, ', test(', I2, ')=', G12.5 ) | |||
| 9996 FORMAT( 1X, A, '( ''', A1, ''', ''', A1, ''', ''', A1, ''', ''', | |||
| @@ -83,9 +83,10 @@ | |||
| EXTERNAL LSAMEN | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAESM, CHKXER, DLATBS, DLATPS, DLATRS, DTBCON, | |||
| $ DTBRFS, DTBTRS, DTPCON, DTPRFS, DTPTRI, DTPTRS, | |||
| $ DTRCON, DTRRFS, DTRTI2, DTRTRI, DTRTRS | |||
| EXTERNAL ALAESM, CHKXER, DLATBS, DLATPS, DLATRS, | |||
| $ DLATRS3, DTBCON, DTBRFS, DTBTRS, DTPCON, | |||
| $ DTPRFS, DTPTRI, DTPTRS, DTRCON, DTRRFS, | |||
| $ DTRTI2, DTRTRI, DTRTRS | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -244,6 +245,46 @@ | |||
| INFOT = 7 | |||
| CALL DLATRS( 'U', 'N', 'N', 'N', 2, A, 1, X, SCALE, W, INFO ) | |||
| CALL CHKXER( 'DLATRS', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| * DLATRS3 | |||
| * | |||
| SRNAMT = 'DLATRS3' | |||
| INFOT = 1 | |||
| CALL DLATRS3( '/', 'N', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL DLATRS3( 'U', '/', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL DLATRS3( 'U', 'N', '/', 'N', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL DLATRS3( 'U', 'N', 'N', '/', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL DLATRS3( 'U', 'N', 'N', 'N', -1, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 6 | |||
| CALL DLATRS3( 'U', 'N', 'N', 'N', 0, -1, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 8 | |||
| CALL DLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 10 | |||
| CALL DLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 2, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 14 | |||
| CALL DLATRS3( 'U', 'N', 'N', 'N', 1, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 0, INFO ) | |||
| CALL CHKXER( 'DLATRS3', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| ELSE IF( LSAMEN( 2, C2, 'TP' ) ) THEN | |||
| * | |||
| @@ -30,7 +30,7 @@ | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> SCHKTR tests STRTRI, -TRS, -RFS, and -CON, and SLATRS | |||
| *> SCHKTR tests STRTRI, -TRS, -RFS, and -CON, and SLATRS(3) | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -187,7 +187,7 @@ | |||
| INTEGER NTYPE1, NTYPES | |||
| PARAMETER ( NTYPE1 = 10, NTYPES = 18 ) | |||
| INTEGER NTESTS | |||
| PARAMETER ( NTESTS = 9 ) | |||
| PARAMETER ( NTESTS = 10 ) | |||
| INTEGER NTRAN | |||
| PARAMETER ( NTRAN = 3 ) | |||
| REAL ONE, ZERO | |||
| @@ -198,13 +198,13 @@ | |||
| CHARACTER*3 PATH | |||
| INTEGER I, IDIAG, IMAT, IN, INB, INFO, IRHS, ITRAN, | |||
| $ IUPLO, K, LDA, N, NB, NERRS, NFAIL, NRHS, NRUN | |||
| REAL AINVNM, ANORM, DUMMY, RCOND, RCONDC, RCONDI, | |||
| $ RCONDO, SCALE | |||
| REAL AINVNM, ANORM, BIGNUM, DUMMY, RCOND, RCONDC, | |||
| $ RCONDI, RCONDO, RES, SCALE, SLAMCH | |||
| * .. | |||
| * .. Local Arrays .. | |||
| CHARACTER TRANSS( NTRAN ), UPLOS( 2 ) | |||
| INTEGER ISEED( 4 ), ISEEDY( 4 ) | |||
| REAL RESULT( NTESTS ) | |||
| REAL RESULT( NTESTS ), SCALE3( 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| @@ -213,9 +213,9 @@ | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAERH, ALAHD, ALASUM, SCOPY, SERRTR, SGET04, | |||
| $ SLACPY, SLARHS, SLATRS, SLATTR, STRCON, STRRFS, | |||
| $ STRT01, STRT02, STRT03, STRT05, STRT06, STRTRI, | |||
| $ STRTRS, XLAENV | |||
| $ SLACPY, SLARHS, SLATRS, SLATRS3, SLATTR, SSCAL, | |||
| $ STRCON, STRRFS, STRT01, STRT02, STRT03, STRT05, | |||
| $ STRT06, STRTRI, STRTRS, XLAENV, SLAMCH | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -239,6 +239,7 @@ | |||
| * | |||
| PATH( 1: 1 ) = 'Single precision' | |||
| PATH( 2: 3 ) = 'TR' | |||
| BIGNUM = SLAMCH('Overflow') / SLAMCH('Precision') | |||
| NRUN = 0 | |||
| NFAIL = 0 | |||
| NERRS = 0 | |||
| @@ -539,6 +540,33 @@ | |||
| $ RWORK, ONE, B( N+1 ), LDA, X, LDA, WORK, | |||
| $ RESULT( 9 ) ) | |||
| * | |||
| *+ TEST 10 | |||
| * Solve op(A)*X = B | |||
| * | |||
| SRNAMT = 'SLATRS3' | |||
| CALL SCOPY( N, X, 1, B, 1 ) | |||
| CALL SCOPY( N, X, 1, B( N+1 ), 1 ) | |||
| CALL SSCAL( N, BIGNUM, B( N+1 ), 1 ) | |||
| CALL SLATRS3( UPLO, TRANS, DIAG, 'N', N, 2, A, LDA, | |||
| $ B, MAX(1, N), SCALE3, RWORK, WORK, NMAX, | |||
| $ INFO ) | |||
| * | |||
| * Check error code from SLATRS3. | |||
| * | |||
| IF( INFO.NE.0 ) | |||
| $ CALL ALAERH( PATH, 'SLATRS3', INFO, 0, | |||
| $ UPLO // TRANS // DIAG // 'Y', N, N, | |||
| $ -1, -1, -1, IMAT, NFAIL, NERRS, NOUT ) | |||
| * | |||
| CALL STRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3 ( 1 ), RWORK, ONE, B( N+1 ), LDA, | |||
| $ X, LDA, WORK, RESULT( 10 ) ) | |||
| CALL SSCAL( N, BIGNUM, X, 1 ) | |||
| CALL STRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 2 ), RWORK, ONE, B( N+1 ), LDA, | |||
| $ X, LDA, WORK, RES ) | |||
| RESULT( 10 ) = MAX( RESULT( 10 ), RES ) | |||
| * | |||
| * Print information about the tests that did not pass | |||
| * the threshold. | |||
| * | |||
| @@ -556,7 +584,14 @@ | |||
| $ DIAG, 'Y', N, IMAT, 9, RESULT( 9 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 2 | |||
| IF( RESULT( 10 ).GE.THRESH ) THEN | |||
| IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 ) | |||
| $ CALL ALAHD( NOUT, PATH ) | |||
| WRITE( NOUT, FMT = 9996 )'SLATRS3', UPLO, TRANS, | |||
| $ DIAG, 'N', N, IMAT, 10, RESULT( 10 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 3 | |||
| 90 CONTINUE | |||
| 100 CONTINUE | |||
| 110 CONTINUE | |||
| @@ -569,8 +604,8 @@ | |||
| 9999 FORMAT( ' UPLO=''', A1, ''', DIAG=''', A1, ''', N=', I5, ', NB=', | |||
| $ I4, ', type ', I2, ', test(', I2, ')= ', G12.5 ) | |||
| 9998 FORMAT( ' UPLO=''', A1, ''', TRANS=''', A1, ''', DIAG=''', A1, | |||
| $ ''', N=', I5, ', NB=', I4, ', type ', I2, ', | |||
| $ test(', I2, ')= ', G12.5 ) | |||
| $ ''', N=', I5, ', NB=', I4, ', type ', I2, ', test(', | |||
| $ I2, ')= ', G12.5 ) | |||
| 9997 FORMAT( ' NORM=''', A1, ''', UPLO =''', A1, ''', N=', I5, ',', | |||
| $ 11X, ' type ', I2, ', test(', I2, ')=', G12.5 ) | |||
| 9996 FORMAT( 1X, A, '( ''', A1, ''', ''', A1, ''', ''', A1, ''', ''', | |||
| @@ -83,9 +83,10 @@ | |||
| EXTERNAL LSAMEN | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAESM, CHKXER, SLATBS, SLATPS, SLATRS, STBCON, | |||
| $ STBRFS, STBTRS, STPCON, STPRFS, STPTRI, STPTRS, | |||
| $ STRCON, STRRFS, STRTI2, STRTRI, STRTRS | |||
| EXTERNAL ALAESM, CHKXER, SLATBS, SLATPS, SLATRS, | |||
| $ SLATRS3, STBCON, STBRFS, STBTRS, STPCON, | |||
| $ STPRFS, STPTRI, STPTRS, STRCON, STRRFS, STRTI2, | |||
| $ STRTRI, STRTRS | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -244,6 +245,46 @@ | |||
| INFOT = 7 | |||
| CALL SLATRS( 'U', 'N', 'N', 'N', 2, A, 1, X, SCALE, W, INFO ) | |||
| CALL CHKXER( 'SLATRS', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| * SLATRS3 | |||
| * | |||
| SRNAMT = 'SLATRS3' | |||
| INFOT = 1 | |||
| CALL SLATRS3( '/', 'N', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL SLATRS3( 'U', '/', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL SLATRS3( 'U', 'N', '/', 'N', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL SLATRS3( 'U', 'N', 'N', '/', 0, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL SLATRS3( 'U', 'N', 'N', 'N', -1, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 6 | |||
| CALL SLATRS3( 'U', 'N', 'N', 'N', 0, -1, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 8 | |||
| CALL SLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 10 | |||
| CALL SLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 2, X, 1, SCALE, W, | |||
| $ W( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 14 | |||
| CALL SLATRS3( 'U', 'N', 'N', 'N', 1, 0, A, 1, X, 1, SCALE, W, | |||
| $ W( 2 ), 0, INFO ) | |||
| CALL CHKXER( 'SLATRS3', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| ELSE IF( LSAMEN( 2, C2, 'TP' ) ) THEN | |||
| * | |||
| @@ -31,7 +31,7 @@ | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> ZCHKTR tests ZTRTRI, -TRS, -RFS, and -CON, and ZLATRS | |||
| *> ZCHKTR tests ZTRTRI, -TRS, -RFS, and -CON, and ZLATRS(3) | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -184,7 +184,7 @@ | |||
| INTEGER NTYPE1, NTYPES | |||
| PARAMETER ( NTYPE1 = 10, NTYPES = 18 ) | |||
| INTEGER NTESTS | |||
| PARAMETER ( NTESTS = 9 ) | |||
| PARAMETER ( NTESTS = 10 ) | |||
| INTEGER NTRAN | |||
| PARAMETER ( NTRAN = 3 ) | |||
| DOUBLE PRECISION ONE, ZERO | |||
| @@ -195,13 +195,13 @@ | |||
| CHARACTER*3 PATH | |||
| INTEGER I, IDIAG, IMAT, IN, INB, INFO, IRHS, ITRAN, | |||
| $ IUPLO, K, LDA, N, NB, NERRS, NFAIL, NRHS, NRUN | |||
| DOUBLE PRECISION AINVNM, ANORM, DUMMY, RCOND, RCONDC, RCONDI, | |||
| $ RCONDO, SCALE | |||
| DOUBLE PRECISION AINVNM, ANORM, BIGNUM, DUMMY, RCOND, RCONDC, | |||
| $ RCONDI, RCONDO, RES, SCALE, DLAMCH | |||
| * .. | |||
| * .. Local Arrays .. | |||
| CHARACTER TRANSS( NTRAN ), UPLOS( 2 ) | |||
| INTEGER ISEED( 4 ), ISEEDY( 4 ) | |||
| DOUBLE PRECISION RESULT( NTESTS ) | |||
| DOUBLE PRECISION RESULT( NTESTS ), SCALE3( 2 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| @@ -209,10 +209,10 @@ | |||
| EXTERNAL LSAME, ZLANTR | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAERH, ALAHD, ALASUM, XLAENV, ZCOPY, ZERRTR, | |||
| $ ZGET04, ZLACPY, ZLARHS, ZLATRS, ZLATTR, ZTRCON, | |||
| $ ZTRRFS, ZTRT01, ZTRT02, ZTRT03, ZTRT05, ZTRT06, | |||
| $ ZTRTRI, ZTRTRS | |||
| EXTERNAL ALAERH, ALAHD, ALASUM, DLAMCH, XLAENV, ZCOPY, | |||
| $ ZDSCAL, ZERRTR, ZGET04, ZLACPY, ZLARHS, ZLATRS, | |||
| $ ZLATRS3, ZLATTR, ZTRCON, ZTRRFS, ZTRT01, | |||
| $ ZTRT02, ZTRT03, ZTRT05, ZTRT06, ZTRTRI, ZTRTRS | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -236,6 +236,7 @@ | |||
| * | |||
| PATH( 1: 1 ) = 'Zomplex precision' | |||
| PATH( 2: 3 ) = 'TR' | |||
| BIGNUM = DLAMCH('Overflow') / DLAMCH('Precision') | |||
| NRUN = 0 | |||
| NFAIL = 0 | |||
| NERRS = 0 | |||
| @@ -380,7 +381,7 @@ | |||
| * This line is needed on a Sun SPARCstation. | |||
| * | |||
| IF( N.GT.0 ) | |||
| $ DUMMY = A( 1 ) | |||
| $ DUMMY = DBLE( A( 1 ) ) | |||
| * | |||
| CALL ZTRT02( UPLO, TRANS, DIAG, N, NRHS, A, LDA, | |||
| $ X, LDA, B, LDA, WORK, RWORK, | |||
| @@ -535,6 +536,32 @@ | |||
| $ RWORK, ONE, B( N+1 ), LDA, X, LDA, WORK, | |||
| $ RESULT( 9 ) ) | |||
| * | |||
| *+ TEST 10 | |||
| * Solve op(A)*X = B | |||
| * | |||
| SRNAMT = 'ZLATRS3' | |||
| CALL ZCOPY( N, X, 1, B, 1 ) | |||
| CALL ZCOPY( N, X, 1, B( N+1 ), 1 ) | |||
| CALL ZDSCAL( N, BIGNUM, B( N+1 ), 1 ) | |||
| CALL ZLATRS3( UPLO, TRANS, DIAG, 'N', N, 2, A, LDA, | |||
| $ B, MAX(1, N), SCALE3, RWORK, WORK, NMAX, | |||
| $ INFO ) | |||
| * | |||
| * Check error code from ZLATRS3. | |||
| * | |||
| IF( INFO.NE.0 ) | |||
| $ CALL ALAERH( PATH, 'ZLATRS3', INFO, 0, | |||
| $ UPLO // TRANS // DIAG // 'N', N, N, | |||
| $ -1, -1, -1, IMAT, NFAIL, NERRS, NOUT ) | |||
| CALL ZTRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 1 ), RWORK, ONE, B( 1 ), LDA, | |||
| $ X, LDA, WORK, RESULT( 10 ) ) | |||
| CALL ZDSCAL( N, BIGNUM, X, 1 ) | |||
| CALL ZTRT03( UPLO, TRANS, DIAG, N, 1, A, LDA, | |||
| $ SCALE3( 2 ), RWORK, ONE, B( N+1 ), LDA, | |||
| $ X, LDA, WORK, RES ) | |||
| RESULT( 10 ) = MAX( RESULT( 10 ), RES ) | |||
| * | |||
| * Print information about the tests that did not pass | |||
| * the threshold. | |||
| * | |||
| @@ -552,7 +579,14 @@ | |||
| $ DIAG, 'Y', N, IMAT, 9, RESULT( 9 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 2 | |||
| IF( RESULT( 10 ).GE.THRESH ) THEN | |||
| IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 ) | |||
| $ CALL ALAHD( NOUT, PATH ) | |||
| WRITE( NOUT, FMT = 9996 )'ZLATRS3', UPLO, TRANS, | |||
| $ DIAG, 'N', N, IMAT, 10, RESULT( 10 ) | |||
| NFAIL = NFAIL + 1 | |||
| END IF | |||
| NRUN = NRUN + 3 | |||
| 90 CONTINUE | |||
| 100 CONTINUE | |||
| 110 CONTINUE | |||
| @@ -565,8 +599,8 @@ | |||
| 9999 FORMAT( ' UPLO=''', A1, ''', DIAG=''', A1, ''', N=', I5, ', NB=', | |||
| $ I4, ', type ', I2, ', test(', I2, ')= ', G12.5 ) | |||
| 9998 FORMAT( ' UPLO=''', A1, ''', TRANS=''', A1, ''', DIAG=''', A1, | |||
| $ ''', N=', I5, ', NB=', I4, ', type ', I2, ', | |||
| $ test(', I2, ')= ', G12.5 ) | |||
| $ ''', N=', I5, ', NB=', I4, ', type ', I2, ', test(', | |||
| $ I2, ')= ', G12.5 ) | |||
| 9997 FORMAT( ' NORM=''', A1, ''', UPLO =''', A1, ''', N=', I5, ',', | |||
| $ 11X, ' type ', I2, ', test(', I2, ')=', G12.5 ) | |||
| 9996 FORMAT( 1X, A, '( ''', A1, ''', ''', A1, ''', ''', A1, ''', ''', | |||
| @@ -82,9 +82,10 @@ | |||
| EXTERNAL LSAMEN | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL ALAESM, CHKXER, ZLATBS, ZLATPS, ZLATRS, ZTBCON, | |||
| $ ZTBRFS, ZTBTRS, ZTPCON, ZTPRFS, ZTPTRI, ZTPTRS, | |||
| $ ZTRCON, ZTRRFS, ZTRTI2, ZTRTRI, ZTRTRS | |||
| EXTERNAL ALAESM, CHKXER, ZLATBS, ZLATPS, ZLATRS, | |||
| $ ZLATRS3, ZTBCON, ZTBRFS, ZTBTRS, ZTPCON, | |||
| $ ZTPRFS, ZTPTRI, ZTPTRS, ZTRCON, ZTRRFS, ZTRTI2, | |||
| $ ZTRTRI, ZTRTRS | |||
| * .. | |||
| * .. Scalars in Common .. | |||
| LOGICAL LERR, OK | |||
| @@ -240,6 +241,46 @@ | |||
| CALL ZLATRS( 'U', 'N', 'N', 'N', 2, A, 1, X, SCALE, RW, INFO ) | |||
| CALL CHKXER( 'ZLATRS', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| * ZLATRS3 | |||
| * | |||
| SRNAMT = 'ZLATRS3' | |||
| INFOT = 1 | |||
| CALL ZLATRS3( '/', 'N', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 2 | |||
| CALL ZLATRS3( 'U', '/', 'N', 'N', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 3 | |||
| CALL ZLATRS3( 'U', 'N', '/', 'N', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 4 | |||
| CALL ZLATRS3( 'U', 'N', 'N', '/', 0, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 5 | |||
| CALL ZLATRS3( 'U', 'N', 'N', 'N', -1, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 6 | |||
| CALL ZLATRS3( 'U', 'N', 'N', 'N', 0, -1, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 8 | |||
| CALL ZLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 10 | |||
| CALL ZLATRS3( 'U', 'N', 'N', 'N', 2, 0, A, 2, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 1, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| INFOT = 14 | |||
| CALL ZLATRS3( 'U', 'N', 'N', 'N', 1, 0, A, 1, X, 1, SCALE, RW, | |||
| $ RW( 2 ), 0, INFO ) | |||
| CALL CHKXER( 'ZLATRS3', INFOT, NOUT, LERR, OK ) | |||
| * | |||
| * Test error exits for the packed triangular routines. | |||
| * | |||
| ELSE IF( LSAMEN( 2, C2, 'TP' ) ) THEN | |||