57 #include "scip/pub_message.h" 58 #include "blockmemshell/memory.h" 59 #include "scip/type_retcode.h" 70 #define BMS_CALL(x) do \ 74 SCIPerrorMessage("No memory in function call\n"); \ 75 return SCIP_NOMEMORY; \ 81 #define SCIP_RealTOINT(x) ((LAPACKINTTYPE) (x + 0.5)) 91 void F77_FUNC(dsyevr, DSYEVR)(
char* JOBZ,
char* RANGE,
char* UPLO,
93 SCIP_Real* VL, SCIP_Real* VU,
95 SCIP_Real* ABSTOL,
LAPACKINTTYPE* M, SCIP_Real* W, SCIP_Real* Z,
101 void F77_FUNC(dsyevx, DSYEVX)(
char* JOBZ,
char* RANGE,
char* UPLO,
103 SCIP_Real* VL, SCIP_Real* VU,
105 SCIP_Real* ABSTOL,
LAPACKINTTYPE* M, SCIP_Real* W, SCIP_Real* Z,
139 assert(
sizeof(work) >
sizeof(checkval));
142 if ( *(int8_t*)&checkval != 0 )
145 if ( *((int8_t*)&num + 4) != 0 )
148 return -(*((
int*)&work));
150 return *((
int*)&num);
154 assert( *(int8_t*)&checkval == 0 );
157 if ( *(int8_t*)&num != 0 )
160 return -(*((
int*)&work + 4));
162 return *((
int*)&num + 4);
176 SCIP_Bool geteigenvectors,
180 SCIP_Real* eigenvalue,
181 SCIP_Real* eigenvector
206 assert( bufmem != NULL );
208 assert( n < INT_MAX );
210 assert( 0 < i && i <= n );
211 assert( eigenvalue != NULL );
212 assert( ! geteigenvectors || eigenvector != NULL );
215 JOBZ = geteigenvectors ?
'V' :
'N';
233 F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
237 &ABSTOL, &M, NULL, NULL,
239 &LWORK, &WISIZE, &LIWORK,
242 if ( convertToInt(INFO) != 0 )
244 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
252 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WORK, (
int) LWORK) );
253 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IWORK, (
int) LIWORK) );
254 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WTMP, (
int) N) );
255 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &ISUPPZ, 2) );
258 F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
262 &ABSTOL, &M, WTMP, eigenvector,
264 &LWORK, IWORK, &LIWORK,
268 if ( convertToInt(INFO) == 0 )
269 *eigenvalue = WTMP[0];
272 BMSfreeBufferMemoryArray(bufmem, &ISUPPZ);
273 BMSfreeBufferMemoryArray(bufmem, &WTMP);
274 BMSfreeBufferMemoryArray(bufmem, &IWORK);
275 BMSfreeBufferMemoryArray(bufmem, &WORK);
277 if ( convertToInt(INFO) != 0 )
279 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
289 SCIP_Bool geteigenvectors,
293 SCIP_Real* eigenvalue,
294 SCIP_Real* eigenvector
317 assert( bufmem != NULL );
319 assert( n < INT_MAX );
321 assert( 0 < i && i <= n );
322 assert( eigenvalue != NULL );
323 assert( ! geteigenvectors || eigenvector != NULL );
326 JOBZ = geteigenvectors ?
'V' :
'N';
343 F77_FUNC(dsyevx, DSYEVX)( &JOBZ, &RANGE, &UPLO,
347 &ABSTOL, &M, NULL, NULL,
348 &LDZ, &WSIZE, &LWORK, NULL, NULL,
351 if ( convertToInt(INFO) != 0 )
353 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
360 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WORK, (
int) LWORK) );
361 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IWORK, (
int) 5 * N) );
362 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WTMP, (
int) N) );
363 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IFAIL, (
int) N) );
366 F77_FUNC(dsyevx, DSYEVX)( &JOBZ, &RANGE, &UPLO,
370 &ABSTOL, &M, WTMP, eigenvector,
371 &LDZ, WORK, &LWORK, IWORK, IFAIL,
375 if ( convertToInt(INFO) == 0 )
376 *eigenvalue = WTMP[0];
379 BMSfreeBufferMemoryArray(bufmem, &IFAIL);
380 BMSfreeBufferMemoryArray(bufmem, &WTMP);
381 BMSfreeBufferMemoryArray(bufmem, &IWORK);
382 BMSfreeBufferMemoryArray(bufmem, &WORK);
384 if ( convertToInt(INFO) != 0 )
386 SCIPerrorMessage(
"There was an error when calling DSYEVX. INFO = %d.\n", convertToInt(INFO));
400 SCIP_Real* eigenvalues,
401 SCIP_Real* eigenvectors
423 assert( bufmem != NULL );
425 assert( n < INT_MAX );
428 assert( neigenvalues != NULL );
429 assert( eigenvalues != NULL );
430 assert( eigenvectors != NULL );
451 F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
455 &ABSTOL, &M, NULL, NULL,
457 &LWORK, &WISIZE, &LIWORK,
461 if ( convertToInt(INFO) != 0 )
463 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
471 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WORK, (
int) LWORK) );
472 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IWORK, (
int) LIWORK) );
473 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &ISUPPZ, (
int) 2 * N) );
476 F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
480 &ABSTOL, &M, eigenvalues, eigenvectors,
482 &LWORK, IWORK, &LIWORK,
486 BMSfreeBufferMemoryArray(bufmem, &ISUPPZ);
487 BMSfreeBufferMemoryArray(bufmem, &IWORK);
488 BMSfreeBufferMemoryArray(bufmem, &WORK);
490 if ( convertToInt(INFO) != 0 )
492 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
496 *neigenvalues = convertToInt(M);
507 SCIP_Real* eigenvalues,
508 SCIP_Real* eigenvectors
530 assert( bufmem != NULL );
532 assert( n < INT_MAX );
534 assert( eigenvalues != NULL );
535 assert( eigenvectors != NULL );
554 F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
558 &ABSTOL, &M, NULL, NULL,
560 &LWORK, &WISIZE, &LIWORK,
563 if ( convertToInt(INFO) != 0 )
565 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
573 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WORK, (
int) LWORK) );
574 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IWORK, (
int) LIWORK) );
575 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &ISUPPZ, (
int) 2 * N) );
578 F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
582 &ABSTOL, &M, eigenvalues, eigenvectors,
584 &LWORK, IWORK, &LIWORK,
588 BMSfreeBufferMemoryArray(bufmem, &ISUPPZ);
589 BMSfreeBufferMemoryArray(bufmem, &IWORK);
590 BMSfreeBufferMemoryArray(bufmem, &WORK);
592 if ( convertToInt(INFO) != 0 )
594 SCIPerrorMessage(
"There was an error when calling DSYEVR. INFO = %d.\n", convertToInt(INFO));
624 assert( nrows < INT_MAX );
626 assert( ncols < INT_MAX );
627 assert( matrix != NULL );
628 assert( vector != NULL );
629 assert( result != NULL );
643 F77_FUNC(dgemv, DGEMV)(&TRANS, &M, &N, &ALPHA, A, &LDA, X, &INCX, &BETA, Y, &INCY);
654 SCIP_Bool transposeA,
658 SCIP_Bool transposeB,
673 assert( nrowsA > 0 );
674 assert( nrowsA < INT_MAX );
675 assert( ncolsA > 0 );
676 assert( ncolsA < INT_MAX );
677 assert( nrowsB > 0 );
678 assert( nrowsB < INT_MAX );
679 assert( ncolsB > 0 );
680 assert( ncolsB < INT_MAX );
681 assert( matrixA != NULL );
682 assert( matrixB != NULL );
683 assert( result != NULL );
685 assert( (transposeA && transposeB && (nrowsA == ncolsB)) || (transposeA && !transposeB && (nrowsA == nrowsB))
686 || (!transposeA && transposeB && (ncolsA == ncolsB)) || (!transposeA && !transposeB && (ncolsA == nrowsB)) );
688 TRANSA = transposeA ?
'T' :
'N';
689 TRANSB = transposeB ?
'T' :
'N';
690 M = transposeA ? ncolsA : nrowsA;
691 N = transposeB ? nrowsB : ncolsB;
692 K = transposeA ? nrowsA : ncolsA;
694 LDA = transposeA ? K : M;
695 LDB = transposeB ? N : K;
699 F77_FUNC(dgemm, DGEMM)(&TRANSA, &TRANSB, &M, &N, &K, &ALPHA, matrixA, &LDA, matrixB, &LDB, &BETA, result, &LDC);
734 assert( bufmem != NULL );
736 assert( m < INT_MAX );
738 assert( n < INT_MAX );
751 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &S, MIN(m,n)) );
757 F77_FUNC(dgelsd, DGELSD)( &M, &N, &NRHS,
758 NULL, &LDA, NULL, &LDB, NULL,
759 &RCOND, &RANK, &WSIZE, &LWORK,
762 if ( convertToInt(INFO) != 0 )
764 SCIPerrorMessage(
"There was an error when calling DGELSD. INFO = %d\n", convertToInt(INFO));
772 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WORK, (
int) LWORK) );
773 BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IWORK, (
int) LIWORK) );
776 F77_FUNC(dgelsd, DGELSD)( &M, &N, &NRHS,
777 A, &LDA, b, &LDB, S, &RCOND, &RANK,
778 WORK, &LWORK, IWORK, &INFO);
782 SCIP_Real residual = 0.0;
784 printf(
"LWORK = %d\n", LWORK);
785 printf(
"LIWORK = %d\n", LIWORK);
786 printf(
"A has size (%d,%d), is of rank %d\n", M, N, RANK);
787 printf(
"Minimum l2-norm solution of linear equation system:\n");
789 for (i = 0; i < n; ++i)
790 printf(
"(%d, %f) ", i, b[i]);
792 for (i = n; i < m; ++i)
793 residual += b[i] * b[i];
796 printf(
"Residual sum-of-squares for the solution is %f\n", residual);
801 BMSfreeBufferMemoryArray(bufmem, &IWORK);
802 BMSfreeBufferMemoryArray(bufmem, &WORK);
803 BMSfreeBufferMemoryArray(bufmem, &S);
805 if ( convertToInt(INFO) != 0 )
807 SCIPerrorMessage(
"There was an error when calling DGELSD. INFO = %d\n", convertToInt(INFO));
812 for (i = 0; i < n; ++i)
#define SCIP_RealTOINT(x)
SCIP_RETCODE SCIPlapackComputeIthEigenvalueAlternative(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
Macros for calling Fortran-functions.
SCIP_RETCODE SCIPlapackMatrixMatrixMult(int nrowsA, int ncolsA, SCIP_Real *matrixA, SCIP_Bool transposeA, int nrowsB, int ncolsB, SCIP_Real *matrixB, SCIP_Bool transposeB, SCIP_Real *result)
long long int LAPACKINTTYPE
SCIP_RETCODE SCIPlapackMatrixVectorMult(int nrows, int ncols, SCIP_Real *matrix, SCIP_Real *vector, SCIP_Real *result)
SCIP_RETCODE SCIPlapackLinearSolve(BMS_BUFMEM *bufmem, int m, int n, SCIP_Real *A, SCIP_Real *b, SCIP_Real *x)
interface methods for eigenvector computation and matrix multiplication using openblas ...
SCIP_RETCODE SCIPlapackComputeEigenvectorsNegative(BMS_BUFMEM *bufmem, int n, SCIP_Real *A, SCIP_Real tol, int *neigenvalues, SCIP_Real *eigenvalues, SCIP_Real *eigenvectors)
#define F77_FUNC(name, NAME)
SCIP_RETCODE SCIPlapackComputeEigenvectorDecomposition(BMS_BUFMEM *bufmem, int n, SCIP_Real *A, SCIP_Real *eigenvalues, SCIP_Real *eigenvectors)
SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)