📄 mmat_00.cc
字号:
// arguments:// long row: (input) first index// long col: (input) second index// long nrows: (input) number of rows// long ncols: (input) number of cols// Integral::MTYPE type: (input) the matrix type//// return: a long value containing storage index of an element of matrix// // since most of the matrix types are stored in a standard vector,// we need a method to facilitate indexing computations - converting from// row and column indices to an array index.//// for efficiency reasons, we do not check whether the requested index// is out of bounds. other methods will catch this (eventually).//// finally, note that for SPARSE, an index will be returned only if// the requested element is explicitly stored in the matrix. if not,// an error handler is called.//template<class TScalar, class TIntegral>long MMatrix<TScalar, TIntegral>::index(long row_a, long col_a, long nrows_a, long ncols_a, Integral::MTYPE type_a) const { // type: UNCHANGED // if (type_a == Integral::UNCHANGED) { return index(row_a, col_a, nrows_a, ncols_a, type_d); } // type: FULL // else if (type_a == Integral::FULL) { return (row_a * ncols_a + col_a); } // type: DIAGONAL // the address must be on the diagonal // else if (type_a == Integral::DIAGONAL) { if (row_a == col_a) { return row_a; } } // type: SYMMETRIC // else if (type_a == Integral::SYMMETRIC) { // check the dimensions: the matrix must be square // if (nrows_a == ncols_a) { // swap the indices if necessary: remember that the lower half of the // symmetric matrix is stored. // long tmp; if (row_a < col_a) { tmp = row_a; row_a = col_a; col_a = tmp; } // now do the typical calculation // return ((row_a * (row_a + 1) / 2) + col_a); } } // type: LOWER_TRIANGULAR // the address must be in the lower part of the matrix, and the matrix // must be square // else if (type_a == Integral::LOWER_TRIANGULAR) { if ((nrows_a == ncols_a) && (row_a >= col_a)) { return ((row_a * (row_a + 1) / 2) + col_a); } } // type: UPPER_TRIANGULAR // the address must be in the upper part of the matrix, and the matrix // must be square // else if (type_a == Integral::UPPER_TRIANGULAR) { if ((nrows_a == ncols_a) && (col_a >= row_a)) { return ((col_a * (col_a + 1) / 2) + row_a); } } // type: SPARSE // find the matching index // else if (type_a == Integral::SPARSE) { // loop over all non-zero elements // long last_index = row_index_d.length(); for (long index = 0; index < last_index; index++) { if ((row_index_d(index) == row_a) && (col_index_d(index) == col_a)) { return index; } } } // exit ungracefully: // if we got this far, there was an indexing error. this can happen // for three reasons: the matrix was a SPARSE matrix; a matrix // required to be square wasn't; or an index was out of range for // the type of matrix given. // this->debug(L"this"); return Error::handle(name(), L"index", Error::ARG, __FILE__, __LINE__);}// method: startRow//// arguments:// long col: (input) col index// Integral::MTYPE type_1: (input) matrix type// Integral::MTYPE type_2: (input) matrix type//// return: a long value containing the column index of the first// available element in a column// // this method is typically used when copying data from one matrix to// the other. it determines the first non-zero value in a given// column that needs to be copied into the destination matrix.// the rules implemented below can be summarized with the following table://// TYPE1 TYPE2// full diag symm ltri utri sprs// full 0 col 0 col 0 0// diag col col col col col col// symm 0 col col col 0 0// ltri col col col col col col// utri 0 col 0 col 0 0// sprs 0 col 0 col 0 0//// this matrix should always be symmetric.//template<class TScalar, class TIntegral>long MMatrix<TScalar, TIntegral>::startRow(long col_a, Integral::MTYPE type_1_a, Integral::MTYPE type_2_a) const { // check the arguments // if (type_2_a == Integral::UNCHANGED) { type_2_a = type_1_a; } // type1: FULL // if (type_1_a == Integral::FULL) { if (type_2_a == Integral::FULL) { return 0; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return 0; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return 0; } else if (type_2_a == Integral::SPARSE) { return 0; } } // type_1: DIAGONAL // else if (type_1_a == Integral::DIAGONAL) { if (type_2_a == Integral::FULL) { return col_a; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return col_a; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return col_a; } } // type_1: SYMMETRIC // else if (type_1_a == Integral::SYMMETRIC) { if (type_2_a == Integral::FULL) { return 0; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return col_a; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return 0; } else if (type_2_a == Integral::SPARSE) { return 0; } } // type_1: LOWER_TRIANGULAR // else if (type_1_a == Integral::LOWER_TRIANGULAR) { if (type_2_a == Integral::FULL) { return col_a; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return col_a; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return col_a; } } // type_1: UPPER_TRIANGULAR // else if (type_1_a == Integral::UPPER_TRIANGULAR) { if (type_2_a == Integral::FULL) { return 0; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return 0; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return 0; } else if (type_2_a == Integral::SPARSE) { return 0; } } // type_1: SPARSE // else if (type_1_a == Integral::SPARSE) { if (type_2_a == Integral::FULL) { return 0; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return 0; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return 0; } else if (type_2_a == Integral::SPARSE) { return 0; } } // type: UNKNOWN // this->debug(L"this"); return Error::handle(name(), L"startRow", Error::ARG, __FILE__, __LINE__);}// method: stopRow//// arguments:// long col: (input) col index// Integral::MTYPE type_1: (input) matrix type// Integral::MTYPE type_2: (input) matrix type//// return: a long value containing the column index of the first// available element in a row// // this method is typically used when copying data from one matrix to// the other. it determines the last non-zero value in a given// column that needs to be copied into the destination matrix.// the rules implemented below can be summarized with the following table://// see startColumn for a detailed description of what this method does.// the rules implemented below can be summarized with the following table://// TYPE1 TYPE2// full diag symm ltri utri sprs// full nrows col nrows nrows col nrows// diag col col col col col col// symm nrows col nrows nrows col nrows// ltri nrows col nrows nrows col nrows// utri col col col col col col// sprs nrows col neows nrows col nrows //// this matrix should always be symmetric.//template<class TScalar, class TIntegral>long MMatrix<TScalar, TIntegral>::stopRow(long col_a, Integral::MTYPE type_1_a, Integral::MTYPE type_2_a) const { // check the arguments // if (type_2_a == Integral::UNCHANGED) { type_2_a = type_1_a; } // type1: FULL // if (type_1_a == Integral::FULL) { if (type_2_a == Integral::FULL) { return (long)nrows_d - 1; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return (long)nrows_d - 1; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return (long)nrows_d - 1; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return (long)nrows_d - 1; } } // type_1: DIAGONAL // else if (type_1_a == Integral::DIAGONAL) { if (type_2_a == Integral::FULL) { return col_a; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return col_a; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return col_a; } } // type_1: SYMMETRIC // else if (type_1_a == Integral::SYMMETRIC) { if (type_2_a == Integral::FULL) { return (long)nrows_d - 1; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return (long)nrows_d - 1; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return (long)nrows_d - 1; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return (long)nrows_d - 1; } } // type_1: LOWER_TRIANGULAR // else if (type_1_a == Integral::LOWER_TRIANGULAR) { if (type_2_a == Integral::FULL) { return (long)nrows_d - 1; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return (long)nrows_d - 1; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return (long)nrows_d - 1; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return (long)nrows_d - 1; } } // type_1: UPPER_TRIANGULAR // else if (type_1_a == Integral::UPPER_TRIANGULAR) { if (type_2_a == Integral::FULL) { return col_a; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return col_a; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return col_a; } } // type_1: SPARSE // else if (type_1_a == Integral::SPARSE) { if (type_2_a == Integral::FULL) { return (long)nrows_d - 1; } else if (type_2_a == Integral::DIAGONAL) { return col_a; } else if (type_2_a == Integral::SYMMETRIC) { return (long)nrows_d - 1; } else if (type_2_a == Integral::LOWER_TRIANGULAR) { return (long)nrows_d - 1; } else if (type_2_a == Integral::UPPER_TRIANGULAR) { return col_a; } else if (type_2_a == Integral::SPARSE) { return (long)nrows_d - 1; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -