📄 mmat_17.cc
字号:
// check arguments // if ((!arg_a.isSquare()) || (!this_a.checkDimensions(arg_a)) || ((this_a.type_d == Integral::DIAGONAL) && (!arg_a.isDiagonal())) || ((this_a.type_d == Integral::UPPER_TRIANGULAR) && (!arg_a.isDiagonal())) || ((this_a.type_d == Integral::SYMMETRIC) && (!arg_a.isDiagonal()))) { arg_a.debug(L"arg_a"); this_a.debug(L"this_a"); return Error::handle(name(), L"setLower", Error::ARG, __FILE__, __LINE__); } // type: FULL, SYMMETRIC, or LOWER_TRIANGULAR // if ((this_a.type_d == Integral::FULL) || (this_a.type_d == Integral::LOWER_TRIANGULAR)) { // copy the lower triangular elements // for (long row = 0; row < this_a.nrows_d; row++) { for (long col = 0; col <= row; col++) { this_a.m_d(this_a.index(row, col)) = arg_a.getValue(row, col); } } } // type: DIAGONAL or UPPER_TRIANGULAR // else if ((this_a.type_d == Integral::DIAGONAL) || (this_a.type_d == Integral::SYMMETRIC) || (this_a.type_d == Integral::UPPER_TRIANGULAR)) { // copy the diagonal elements // for (long row = 0; row < this_a.nrows_d; row++) { this_a.m_d(this_a.index(row, row)) = arg_a.getValue(row, row); } } // type: SPARSE // else { // the only really clean way to do this is to manually copy all // the non-zero elements. for a truly sparse matrix, this won't be // prohibitively expensive. // for (long row = 0; row < this_a.nrows_d; row++) { for (long col = 0; col <= row; col++) { // since looking up this value is expensive, we want to save it // TIntegral tmp = arg_a.getValue(row, col); // add the value if it is non-zero // if (tmp != 0) { this_a.setValue(row, col, tmp); } } } } // exit gracefully // return true;}// explicit instantiations//template booleanMMatrixMethods::setLower<ISIP_TEMPLATE_TARGET>(MMatrix<ISIP_TEMPLATE_TARGET>&, const MMatrix<ISIP_TEMPLATE_TARGET>&);// method: setUpper//// arguments:// MMatrix<TScalar, TIntegral>& this: (output) class operand// const MMatrix<TScalar, TIntegral>& arg: (input) new values//// return: a boolean value indicating status//// this method sets the lower triangular elements of the matrix to be// the same as the lower triangular elements of the source matrix//template<class TScalar, class TIntegral>boolean MMatrixMethods::setUpper(MMatrix<TScalar, TIntegral>& this_a, const MMatrix<TScalar, TIntegral>& arg_a) { // check arguments // if ((!arg_a.isSquare()) || (!this_a.checkDimensions(arg_a)) || ((this_a.type_d == Integral::DIAGONAL) && (!arg_a.isDiagonal())) || ((this_a.type_d == Integral::LOWER_TRIANGULAR) && (!arg_a.isDiagonal())) || ((this_a.type_d == Integral::SYMMETRIC) && (!arg_a.isDiagonal()))) { arg_a.debug(L"arg_a"); this_a.debug(L"this_a"); return Error::handle(name(), L"setUpper", Error::ARG, __FILE__, __LINE__); } // type: FULL, SYMMETRIC, or UPPER_TRIANGULAR // if ((this_a.type_d == Integral::FULL) || (this_a.type_d == Integral::UPPER_TRIANGULAR)) { // copy the upper triangular elements // for (long row = 0; row < this_a.nrows_d; row++) { for (long col = row; col < this_a.nrows_d; col++) { this_a.m_d(this_a.index(row, col)) = arg_a.getValue(row, col); } } } // type: DIAGONAL, SYMMETRIC or LOWER_TRIANGULAR // else if ((this_a.type_d == Integral::DIAGONAL) || (this_a.type_d == Integral::SYMMETRIC) || (this_a.type_d == Integral::LOWER_TRIANGULAR)) { // copy the diagonal elements // for (long row = 0; row < this_a.nrows_d; row++) { this_a.m_d(this_a.index(row, row)) = arg_a.getValue(row, row); } } // type: SPARSE // else { // the only really clean way to do this is to manually copy all // the non-zero elements. for a truly sparse matrix, this won't be // prohibitively expensive. // for (long row = 0; row < this_a.nrows_d; row++) { for (long col = row; col < this_a.ncols_d; col++) { // since looking up this value is expensive, we want to save it // TIntegral tmp = arg_a.getValue(row, col); // add the value if it is non-zero // if (tmp != 0) { this_a.setValue(row, col, tmp); } } } } // exit gracefully // return true;}// explicit instantiations//template booleanMMatrixMethods::setUpper<ISIP_TEMPLATE_TARGET>(MMatrix<ISIP_TEMPLATE_TARGET>&, const MMatrix<ISIP_TEMPLATE_TARGET>&);// method: setBlock//// arguments:// MMatrix<TScalar, TIntegral>& this_a: (input) operand// long start_row: (input) starting row// long start_col: (input) starting column// long nrows: (input) number of rows// long ncols: (input) number of columns// TIntegral value: (input) operand//// return: a boolean value indicating status//// this method assigns the input value to a block of a matrix// in the range://// [start_row, start_col] to // [start_row + nrows - 1, start_col + ncols - 1]//// the type of the matrix is not changed.//template<class TScalar, class TIntegral>boolean MMatrixMethods::setBlock(MMatrix<TScalar, TIntegral>& this_a, long start_row_a, long start_col_a, long nrows_a, long ncols_a, TIntegral value_a) { // declare local variables // long start_row = start_row_a; long start_col = start_col_a; long end_row = start_row_a + nrows_a; long end_col = start_col_a + ncols_a; // check the dimensions against the overall dimensions of the matrix // if ((start_row < (long)0) || (end_row > (long)this_a.nrows_d) || (start_col < (long)0) || (end_col > (long)this_a.ncols_d)) { this_a.debug(L"this_a"); return Error::handle(name(), L"setBlock", Error::ARG, __FILE__, __LINE__); } else if ((nrows_a == 0) || (ncols_a == 0)) { return true; } // type: FULL // assign the value manually to each element // if (this_a.type_d == Integral::FULL) { for (long row = start_row; row < end_row; row++) { for (long col = start_col; col < end_col; col++) { this_a.m_d(this_a.index(row, col)) = value_a; } } } // type: DIAGONAL // else if (this_a.type_d == Integral::DIAGONAL) { // as we assign values, check for zero. // for (long row = start_row; row < end_row; row++) { for (long col = start_col; col < end_col; col++) { if ((row != col) && (value_a != 0)) { this_a.debug(L"this_a"); return Error::handle(name(), L"setBlock", Error::ARG, __FILE__, __LINE__); } else if (row = col) { this_a.m_d(this_a.index(row, col)) = value_a; } } } } // type: SYMMETRIC // else if (this_a.type_d == Integral::SYMMETRIC) { // the block must also be one of three things: // - completely in the lower half (in which case, we allow it) // - completely in the upper half (in which case, we allow it) // - centered on the diagonal and square // if (((start_col > start_row) && (start_col < (end_row - 1))) || ((start_col < start_row) && (start_col > (end_row - 1))) || ((start_row == start_col) && (nrows_a != ncols_a))) { this_a.debug(L"this_a"); return Error::handle(name(), L"setBlock", Error::ARG, __FILE__, __LINE__); } // we can proceed with assigning values. we could be more efficient // about this, but it is not trivial to get the indexing correct. // for (long row = start_row; row < end_row; row++) { for (long col = start_col; col < end_col; col++) { this_a.m_d(this_a.index(row, col)) = value_a; } } } // type: LOWER_TRIANGULAR // else if (this_a.type_d == Integral::LOWER_TRIANGULAR) { // as we assign values, check for zero. // for (long row = start_row; row < end_row; row++) { for (long col = start_col; col < end_col; col++) { if ((col > row) && (value_a != 0)) { this_a.debug(L"this_a"); return Error::handle(name(), L"setBlock", Error::ARG, __FILE__, __LINE__); } else if (row >= col) { this_a.m_d(this_a.index(row, col)) = value_a; } } } } // type: UPPER_TRIANGULAR // else if (this_a.type_d == Integral::UPPER_TRIANGULAR) { // as we assign values, check for zero. // for (long row = start_row; row < end_row; row++) { for (long col = start_col; col < end_col; col++) { if ((row > col) && (value_a != 0)) { this_a.debug(L"this_a"); return Error::handle(name(), L"setBlock", Error::ARG, __FILE__, __LINE__); } else if (col >= row) { this_a.m_d(this_a.index(row, col)) = value_a; } } } } // type: SPARSE // essentially the same as FULL, but we use the setValue method // else { for (long row = start_row; row < end_row; row++) { for (long col = start_col; col < end_col; col++) { this_a.setValue(row, col, value_a); } } } // exit gracefully // return true;}// explicit instantiations//template booleanMMatrixMethods::setBlock<ISIP_TEMPLATE_TARGET>(MMatrix<ISIP_TEMPLATE_TARGET>&, long, long, long, long, ISIP_TEMPLATE_T1);// method: makeDiagonal//// arguments:// MMatrix<TScalar, TIntegral>& this: (output) class operand// const MVector<TScalar, TIntegral>& values: (input) new values// Integral::MTYPE type: (input) expected matrix type//// return: a boolean value indicating status//// this method creates a diagonal matrix from an input vector//template<class TScalar, class TIntegral>booleanMMatrixMethods::makeDiagonal(MMatrix<TScalar, TIntegral>& this_a, const MVector<TScalar, TIntegral>& values_a, Integral::MTYPE type_a) { // get the required dimensions of the matrix // long dim = values_a.length(); // set the dimensions of the matrix // this_a.setDimensions(dim, dim, false, type_a); // type: DIAGONAL // simply assign the input vector to the storage vector // if (type_a == Integral::DIAGONAL) { this_a.m_d.assign(values_a); } // type: FULL, SYMMETRIC, or TRIANGULAR // else if ((this_a.type_d == Integral::FULL) || (this_a.type_d == Integral::SYMMETRIC) || (this_a.type_d == Integral::LOWER_TRIANGULAR) || (this_a.type_d == Integral::UPPER_TRIANGULAR)) { // clear the contents of the current matrix // this_a.clear(Integral::RETAIN); // assign values to the diagonal elements of the matrix // for (long row = 0; row < dim; row++) { this_a.m_d(this_a.index(row, row)) = values_a(row); } } // type: SPARSE // else if (this_a.type_d == Integral::SPARSE) { // find the number of non-zero diagonal elements // long dim_nonzero = values_a.numNotEqual(0); // create space in the sparse vectors // this_a.m_d.setLength(dim_nonzero); this_a.row_index_d.setLength(dim_nonzero); this_a.col_index_d.setLength(dim_nonzero); // loop over the diagonal elements // for (long row = 0, index = 0; row < dim; row++) { // only assign the non-zero values // TIntegral tmp = values_a(row); if (tmp != 0) { this_a.m_d(index) = tmp; this_a.row_index_d(index) = row; this_a.col_index_d(index++) = row; } } } // exit gracefully // return true;}// explicit instantiations//template booleanMMatrixMethods::makeDiagonal<ISIP_TEMPLATE_TARGET>(MMatrix<ISIP_TEMPLATE_TARGET>&, const MVector<ISIP_TEMPLATE_TARGET>&, Integral::MTYPE);// method: makeLower//// arguments:// MMatrix<TScalar, TIntegral>& this: (output) class operand// const MMatrix<TScalar, TIntegral>& arg: (input) new values// Integral::MTYPE type: (input) expected matrix type//// return: a boolean value indicating status//template<class TScalar, class TIntegral>boolean MMatrixMethods::makeLower(MMatrix<TScalar, TIntegral>& this_a, const MMatrix<TScalar, TIntegral>& arg_a, Integral::MTYPE type_a) { // change the type // this_a.clear(Integral::RESET); this_a.changeType(type_a); // make the new matrix // return arg_a.getLower(this_a);}// explicit instantiations//template booleanMMatrixMethods::makeLower<ISIP_TEMPLATE_TARGET>(MMatrix<ISIP_TEMPLATE_TARGET>&, const MMatrix<ISIP_TEMPLATE_TARGET>&, Integral::MTYPE);// method: makeUpper//// arguments:// MMatrix<TScalar, TIntegral>& this: (output) class operand// const MMatrix<TScalar, TIntegral>& arg: (input) new values// Integral::MTYPE type: (input) expected matrix type//// return: a boolean value indicating status//template<class TScalar, class TIntegral>boolean MMatrixMethods::makeUpper(MMatrix<TScalar, TIntegral>& this_a, const MMatrix<TScalar, TIntegral>& arg_a, Integral::MTYPE type_a) { // change the type // this_a.clear(Integral::RESET); this_a.changeType(type_a); // make the new matrix // return arg_a.getUpper(this_a);}// explicit instantiations//template booleanMMatrixMethods::makeUpper<ISIP_TEMPLATE_TARGET>(MMatrix<ISIP_TEMPLATE_TARGET>&, const MMatrix<ISIP_TEMPLATE_TARGET>&, Integral::MTYPE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -