Macaulay2 Engine
Loading...
Searching...
No Matches

◆ QR() [1/2]

bool Lapack::QR ( const DMatCC * A,
DMatCC * Q,
DMatCC * R,
bool return_QR )
static

Definition at line 1009 of file lapack.cpp.

1010{
1011 // sizes:
1012 // input: A[m,n]
1013 // output for returnQR==true:
1014 // case m >= n: Q[m,n], R[n,n]
1015 // case m < n: Q[m,m], R[m,n]
1016 // output for returnQR==false:
1017 // Q[m,n], R[1,min(m,n)]
1018 bool ret = true;
1019 int rows = static_cast<int>(A->numRows());
1020 int cols = static_cast<int>(A->numColumns());
1021 int info1 = 0, info2 = 0, info3 = 0, info4 = 0;
1022 int min = (rows <= cols) ? rows : cols;
1023
1024 if (min == 0)
1025 {
1026 ERROR("expected a matrix with positive dimensions");
1027 return false;
1028 }
1029
1030 std::vector<double> copyA = make_lapack_array(*A); // delete as well.
1031 std::vector<double> tau (10*min); // TODO: set to 0?
1032 double workspace_size[1];
1033 int work_size = -1;
1034 // find optimal workspace
1035 zgeqrf_(&rows, &cols, copyA.data(), &rows, tau.data(), workspace_size, &work_size, &info1);
1036 work_size = static_cast<int>(workspace_size[0]);
1037 double *workspace = new double[20 * work_size];
1038
1039 zgeqrf_(&rows, &cols, copyA.data(), &rows, tau.data(), workspace, &work_size, &info2);
1040
1041 if (info1 < 0 or info2 < 0)
1042 {
1043 ERROR("argument passed to zgeqrf had an illegal value");
1044 ret = false;
1045 }
1046 if (info1 > 0 or info2 > 0)
1047 {
1048 ERROR("can this happen?");
1049 ret = false;
1050 }
1051
1052 if (ret)
1053 {
1054 if (return_QR)
1055 {
1056 Q->resize(rows, cols);
1057 R->resize(cols, cols);
1058 fill_from_lapack_upper(copyA, rows, cols, *R);
1059
1060 // Reset Q, R, with their values.
1061 int orgqr_work_size = -1;
1062 zungqr_(&rows,
1063 &cols,
1064 &min,
1065 copyA.data(),
1066 &rows, // lda?
1067 tau.data(),
1068 workspace_size,
1069 &orgqr_work_size,
1070 &info3);
1071 orgqr_work_size = static_cast<int>(workspace_size[0]);
1072 if (orgqr_work_size > work_size)
1073 {
1074 delete[] workspace;
1075 work_size = orgqr_work_size;
1076 workspace = new double[2 * work_size];
1077 }
1078 zungqr_(&rows,
1079 &cols,
1080 &min,
1081 copyA.data(),
1082 &rows, // lda?
1083 tau.data(),
1084 workspace,
1085 &work_size,
1086 &info4);
1087 if (info3 < 0 or info4 < 0)
1088 {
1089 ERROR("argument passed to dorgqr or dorgqr had an illegal value");
1090 ret = false;
1091 }
1092 else if (info3 > 0 or info4 > 0)
1093 {
1094 ERROR("can this happen?");
1095 ret = false;
1096 }
1097 else
1098 {
1099 fill_from_lapack_array(copyA, *Q);
1100 }
1101 }
1102 else
1103 {
1104 // Return the raw values for QR: the "A" matrix encodes R and the
1105 // Householders, and tau has the multipliers.
1106 Q->resize(rows, cols);
1107 R->resize(1, min);
1108 fill_from_lapack_array(copyA, *Q);
1109 fill_from_lapack_array(tau, *R);
1110 }
1111 }
1112
1113 delete[] workspace;
1114 return ret;
1115}
size_t numRows() const
Definition dmat.hpp:144
void resize(size_t new_nrows, size_t new_ncols)
Definition dmat.hpp:157
size_t numColumns() const
Definition dmat.hpp:145
std::vector< double > make_lapack_array(const DMatRR &mat)
Definition lapack.cpp:20
void fill_from_lapack_array(const std::vector< double > &doubles, DMatRR &mat)
Definition lapack.cpp:45
void fill_from_lapack_upper(const std::vector< double > &lapack_numbers, int numrows, int numcols, DMatRR &upper)
Definition lapack.cpp:74
int zgeqrf_(int *m, int *n, double *A, int *lda, double *tau, double *work, int *lwork, int *info)
int zungqr_(int *m, int *n, int *k, double *A, int *lda, double *tau, double *work, int *lwork, int *info)
const int ERROR
Definition m2-mem.cpp:55
const mpreal min(const mpreal &x, const mpreal &y)
Definition mpreal.h:2792

References ERROR, fill_from_lapack_array(), fill_from_lapack_upper(), make_lapack_array(), DMat< ACoeffRing >::numColumns(), DMat< ACoeffRing >::numRows(), DMat< ACoeffRing >::resize(), zgeqrf_(), and zungqr_().