/***********************************************************************//** * @brief Insert vector column into matrix * * @param[in] vector Vector. * @param[in] col Column index (starting from 0). * * @exception GException::out_of_range * Invalid column index specified. * @exception GException::matrix_vector_mismatch * Matrix dimension mismatches the vector size. * * Inserts the content of a vector into a matrix column. Any previous * content in the matrix column will be overwritted. ***************************************************************************/ void GMatrix::insert_col(const GVector& vector, const int& col) { // Raise an exception if the column index is invalid #if defined(G_RANGE_CHECK) if (col < 0 || col >= m_cols) { throw GException::out_of_range(G_INSERT_COL, col, 0, m_cols-1); } #endif // Raise an exception if the matrix and vector dimensions are not // compatible if (m_rows != vector.size()) { throw GException::matrix_vector_mismatch(G_INSERT_COL, vector.size(), m_rows, m_cols); } // Continue only if we have elements if (m_elements > 0) { // Get start index of data in matrix int i = m_colstart[col]; // Insert column into vector for (int row = 0; row < m_rows; ++row) { m_data[i++] = vector[row]; } } // endif: matrix had elements // Return return; }
/***********************************************************************//** * @brief Vector multiplication * * @param[in] vector Vector. * * @exception GException::matrix_vector_mismatch * Vector length differs from number of columns in matrix. * * This method performs a vector multiplication of a matrix. The vector * multiplication will produce a vector. The matrix multiplication can only * be performed when the number of matrix columns is equal to the length of * the vector. ***************************************************************************/ GVector GMatrix::operator*(const GVector& vector) const { // Raise an exception if the matrix and vector dimensions are not compatible if (m_cols != vector.size()) { throw GException::matrix_vector_mismatch(G_OP_MUL_VEC, vector.size(), m_rows, m_cols); } // Perform vector multiplication GVector result(m_rows); for (int row = 0; row < m_rows; ++row) { double sum = 0.0; for (int col = 0; col < m_cols; ++col) { sum += (*this)(row,col) * vector[col]; } result[row] = sum; } // Return result return result; }
void discard(typename Factory::Set& s, GVector<typename Factory::Set > &sv, GVector<typename Factory::Solution > &solv, FT record, BNBBranchInfo* info) { int n = s.mA.size(); int I = s.mSplitI; int m = s.mSegments.size(); if(m > 0) { for(int i = 0; i <= m; i ++) { typename Factory::Set sn(n); bool put = false; for(int j = 0; j < n; j ++) { sn.mA[j] = s.mA[j]; sn.mB[j] = s.mB[j]; } if(i == 0) { Segment<FT> seg = s.mSegments.at(i); if(s.mA[I] < seg.mA) { sn.mB[I] = seg.mA; put = true; } } else if(i == m) { Segment<FT> pseg = s.mSegments.at(i-1); if(s.mB[I] > pseg.mB) { sn.mA[I] = pseg.mB; put = true; } } else { Segment<FT> pseg = s.mSegments.at(i-1); Segment<FT> seg = s.mSegments.at(i); sn.mA[I] = pseg.mB; sn.mB[I] = seg.mA; put = true; } if(put) { sn.mSplitI = BoxUtils::getLongestEdge(sn); sv.push_back(sn); } } if(sv.size() == 1) { typename Factory::Set ss; ss = sv[0]; sv.pop_back(); split(ss, sv); } } else { split(s, sv); } if(!sv.empty()) info->mBranched ++; }
/***********************************************************************//** * @brief Insert vector column into matrix * * @param[in] vector Vector. * @param[in] col Column index (starting from 0). * * @exception GException::out_of_range * Invalid column index specified. * @exception GException::matrix_vector_mismatch * Matrix dimension mismatches the vector size. * * Inserts the content of a vector into a matrix column. Any previous * content in the matrix column will be overwritted. ***************************************************************************/ void GSymMatrix::insert_col(const GVector& vector, const int& col) { // Raise an exception if the column index is invalid #if defined(G_RANGE_CHECK) if (col < 0 || col >= m_cols) { throw GException::out_of_range(G_INSERT_COL, col, 0, m_cols-1); } #endif // Raise an exception if the matrix and vector dimensions are not // compatible if (m_rows != vector.size()) { throw GException::matrix_vector_mismatch(G_INSERT_COL, vector.size(), m_rows, m_cols); } // Insert column into vector for (int row = 0; row < m_rows; ++row) { (*this)(row,col) = vector[row]; } // Return return; }
/** * MANDATORY, decompose rectangle * * @param s set, representing rectangle to decompose * * @param sv resulting two (or more) rectangles * * @param record the incumbent value * */ virtual void branch (Set & s, GVector < Set > & sv, GVector < Solution > & solv, Solution & incumbent, BNBBranchInfo * info, InfiniInt ql) { bool rv; Set asetv[MAX_BNB_CHILDREN]; FixedVector < Set > setv(asetv, MAX_BNB_CHILDREN); rv = false; sv.push_back(s); if(!mDiscarders.empty()) { int sz = mDiscarders.size(); for(int i = 0; i < sz; i++){ if(sv.empty()) break; while(!sv.empty()) { Set s = sv.back(); sv.pop_back(); mDiscarders[i]->discard(s, setv, solv, incumbent, info); } int sz = setv.size(); for(int i = 0; i < sz; i ++) { sv.push_back(setv[i]); } setv.clear(); //sv.insert(sv.end(), setv.begin(), setv.end()); } } //TODO make selection of sets to produce solutions int sz = sv.size(); for(int i = 0; i < sz; i ++) { Solution sol; if(makeSolution(sv[i], sol)) solv.push_back(sol); } /* if(mOptions & Options::DO_LOCAL_SEARCH) { int sz = solv.size(); for(int i = 0; i < sz; i++){ improveSolution(solv[i]); } } */ }
/***********************************************************************//** * @brief Cholesky solver * * @param[in] vector Vector for which should be solved. * @param[in] compress Use zero-row/column compression (default: true). * * @exception GException::matrix_vector_mismatch * Matrix and vector do not match. * @exception GException::matrix_zero * All matrix elements are zero. * * Solves the linear equation A*x=b using a Cholesky decomposition of A. * This function is to be applied on a decomposition GSymMatrix matrix * that is produced by 'cholesky_decompose'. Case A operates on a full * matrix, Case B on a zero rows/columns (logically) compressed matrix. ***************************************************************************/ GVector GSymMatrix::cholesky_solver(const GVector& vector, bool compress) { // Raise an exception if the matrix and vector dimensions are not compatible if (m_rows != vector.size()) { throw GException::matrix_vector_mismatch(G_CHOL_SOLVE, vector.size(), m_rows, m_cols); } // Allocate result vector GVector x(m_rows); // Check if zero-row/col compression is needed int no_zeros = ((compress && (m_num_inx == m_rows)) || !compress); // Case A: no zero-row/col compression needed if (no_zeros) { // Solve L*y=b, storing y in x (row>k) for (int row = 0; row < m_rows; ++row) { double sum = vector[row]; for (int k = 0; k < row; ++k) { sum -= m_data[m_colstart[k]+(row-k)] * x[k]; // sum -= M(row,k) * x(k) } x[row] = sum/m_data[m_colstart[row]]; // x(row) = sum/M(row,row) } // Solve trans(L)*x=y (k>row) for (int row = m_rows-1; row >= 0; --row) { double sum = x[row]; double* ptr = m_data + m_colstart[row] + 1; for (int k = row+1; k < m_rows; ++k) { sum -= *ptr++ * x[k]; // sum -= M(k,row) * x(k) } x[row] = sum/m_data[m_colstart[row]]; // x(row) = sum/M(row,row) } } // endif: no zero-row/col compression needed // Case B: zero-row/col compression needed else if (m_num_inx > 0) { // Allocate loop variables and pointers int row; int k; int* row_ptr; int* k_ptr; // Solve L*y=b, storing y in x (row>k) for (row = 0, row_ptr = m_inx; row < m_num_inx; ++row, ++row_ptr) { double sum = vector[*row_ptr]; double* ptr = m_data + *row_ptr; for (k = 0, k_ptr = m_inx; k < row; ++k, ++k_ptr) { sum -= *(ptr + m_colstart[*k_ptr] - *k_ptr) * x[*k_ptr]; // sum -= M(row,k) * x(k) } x[*row_ptr] = sum/m_data[m_colstart[*row_ptr]]; // x(row) = sum/M(row,row) } // Solve trans(L)*x=y (k>row) for (row = m_num_inx-1, row_ptr = m_inx+m_num_inx-1; row >= 0; --row, --row_ptr) { double sum = x[*row_ptr]; double* ptr_diag = m_data + m_colstart[*row_ptr]; double* ptr = ptr_diag - *row_ptr; for (k = row+1, k_ptr = m_inx+row+1; k < m_num_inx; ++k, ++k_ptr) { sum -= *(ptr + *k_ptr) * x[*k_ptr]; // sum -= M(k,row) * x(k) } x[*row_ptr] = sum/(*ptr_diag); // x(row) = sum/M(row,row) } } // endelse: zero-row/col compression needed // Case C: all matrix elements are zero else { throw GException::matrix_zero(G_CHOL_SOLVE); } // Return result vector return x; }