Commit ac8208884b848fbe81a683effe5f07c54883a0e7

Authored by Jürgen Knödlseder
1 parent 3c121781

Use bisection for row search in GMatrixSparse::row() and GMatrixSparse::get_index() methods.

Bisection is substantially faster then the previous looping over all elements in a column.
Showing 1 changed file with 53 additions and 29 deletions
src/linalg/GMatrixSparse.cpp
... ... @@ -804,18 +804,26 @@ GVector GMatrixSparse::row(const int& row) const
804 804 int i_start = m_colstart[col];
805 805 int i_stop = m_colstart[col+1];
806 806  
807   - // Search requested row in elements
808   - int i;
809   - for (i = i_start; i < i_stop; ++i) {
810   - if (m_rowinx[i] == row) {
811   - break;
  807 + // If column is not empty then search requested row by bisection
  808 + if (i_stop > i_start) {
  809 +
  810 + // Find row by bisection
  811 + while ((i_stop - i_start) > 1) {
  812 + int mid = (i_start+i_stop) / 2;
  813 + if (m_rowinx[mid] > row) {
  814 + i_stop = mid;
  815 + }
  816 + else {
  817 + i_start = mid;
  818 + }
812 819 }
813   - }
814 820  
815   - // Copy element if we found one
816   - if (i < i_stop) {
817   - result[col] = m_data[i];
818   - }
  821 + // Copy element if we found the row
  822 + if (m_rowinx[i_start] == row) {
  823 + result[col] = m_data[i_start];
  824 + }
  825 +
  826 + } // endif: column was not empty
819 827  
820 828 } // endfor: looped over all columns
821 829  
... ... @@ -2786,40 +2794,56 @@ void GMatrixSparse::free_stack_members(void)
2786 2794 *
2787 2795 * @param[in] row Row index.
2788 2796 * @param[in] column Column index.
  2797 + * @return Element index.
2789 2798 *
2790 2799 * Returns the index in the compressed array for (row,col). The following
2791 2800 * special results exist:
2792   - * -1: Requested index does not exist in the matrix.
2793   - * m_elements: Requested index is the pending element.
  2801 + *
  2802 + * -1: Requested index does not exist in the matrix.
  2803 + * m_elements: Requested index is the pending element.
2794 2804 ***************************************************************************/
2795 2805 int GMatrixSparse::get_index(const int& row, const int& column) const
2796 2806 {
2797 2807 // Initialise element to 'not found'
2798 2808 int index = -1;
2799 2809  
2800   - // If we have a pending element then check if this element is requested
2801   - if (m_fill_val != 0.0) {
2802   - if (row == m_fill_row && column == m_fill_col) {
2803   - return m_elements;
2804   - }
  2810 + // If we have a pending element and the pending element is requested
  2811 + // then return m_elements as index
  2812 + if ((m_fill_val != 0.0) && (row == m_fill_row && column == m_fill_col)) {
  2813 + index = m_elements;
2805 2814 }
  2815 +
  2816 + // ... otherwise if there are elements in the matrix then search for
  2817 + // the requested row and column.
  2818 + else if (m_elements > 0) {
2806 2819  
2807   - // If requested element is not the pending element then check if it exists
2808   - // in the matrix. Only if it is found its index is returned. Otherwise
2809   - // the default index is -1, signalling that the element is absent.
2810   - if (m_elements > 0) {
  2820 + // Get the start and stop of the elements
2811 2821 int* ptr_colstart = m_colstart + column;
2812 2822 int i_start = *ptr_colstart++;
2813 2823 int i_stop = *ptr_colstart;
2814   - int* ptr_rowinx = m_rowinx + i_start;
2815   - for (int i = i_start; i < i_stop; ++i) {
2816   - int row_test = *ptr_rowinx++;
2817   - if (row_test == row) {
2818   - index = i;
2819   - break;
  2824 +
  2825 + // If column is not empty then search requested row by bisection
  2826 + if (i_stop > i_start) {
  2827 +
  2828 + // Find row by bisection
  2829 + while ((i_stop - i_start) > 1) {
  2830 + int mid = (i_start+i_stop) / 2;
  2831 + if (m_rowinx[mid] > row) {
  2832 + i_stop = mid;
  2833 + }
  2834 + else {
  2835 + i_start = mid;
  2836 + }
2820 2837 }
2821   - }
2822   - }
  2838 +
  2839 + // If we found the row then store the index
  2840 + if (m_rowinx[i_start] == row) {
  2841 + index = i_start;
  2842 + }
  2843 +
  2844 + } // endif: column was not empty
  2845 +
  2846 + } // endif: matrix contained elements
2823 2847  
2824 2848 // Return index
2825 2849 return index;
... ...