| SpMat_meat.hpp | | SpMat_meat.hpp | |
| | | | |
| skipping to change at line 579 | | skipping to change at line 579 | |
| SpMat<eT> z(n_rows, p.get_n_cols()); | | SpMat<eT> z(n_rows, p.get_n_cols()); | |
| | | | |
| z.mem_resize(nonzero_rows * p.get_n_cols()); // upper bound on size | | z.mem_resize(nonzero_rows * p.get_n_cols()); // upper bound on size | |
| | | | |
| // Now we have to fill all the elements using a modification of the NUMBM
M algorithm. | | // Now we have to fill all the elements using a modification of the NUMBM
M algorithm. | |
| uword cur_pos = 0; | | uword cur_pos = 0; | |
| | | | |
| podarray<eT> partial_sums(n_rows); | | podarray<eT> partial_sums(n_rows); | |
| partial_sums.zeros(); | | partial_sums.zeros(); | |
| | | | |
|
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | for(uword col = 0; col < n_cols; ++col) | |
| { | | { | |
| const_iterator it = begin(); | | const_iterator it = begin(); | |
| | | | |
| while(it != end()) | | while(it != end()) | |
| { | | { | |
| const eT value = (*it); | | const eT value = (*it); | |
| | | | |
|
| partial_sums[it.row()] += (value * p.at(it.col(), lcol)); | | partial_sums[it.row()] += (value * p.at(it.col(), col)); | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| // Now add all partial sums to the matrix. | | // Now add all partial sums to the matrix. | |
| for(uword i = 0; i < n_rows; ++i) | | for(uword i = 0; i < n_rows; ++i) | |
| { | | { | |
| if(partial_sums[i] != eT(0)) | | if(partial_sums[i] != eT(0)) | |
| { | | { | |
| access::rw(z.values[cur_pos]) = partial_sums[i]; | | access::rw(z.values[cur_pos]) = partial_sums[i]; | |
| access::rw(z.row_indices[cur_pos]) = i; | | access::rw(z.row_indices[cur_pos]) = i; | |
|
| ++access::rw(z.col_ptrs[lcol + 1]); | | ++access::rw(z.col_ptrs[col + 1]); | |
| //printf("colptr %d now %d\n", lcol + 1, z.col_ptrs[lcol + 1]); | | //printf("colptr %d now %d\n", col + 1, z.col_ptrs[col + 1]); | |
| ++cur_pos; | | ++cur_pos; | |
| partial_sums[i] = 0; // Would it be faster to do this in batch late
r? | | partial_sums[i] = 0; // Would it be faster to do this in batch late
r? | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| // Now fix the column pointers. | | // Now fix the column pointers. | |
| for(uword c = 1; c <= z.n_cols; ++c) | | for(uword c = 1; c <= z.n_cols; ++c) | |
| { | | { | |
| access::rw(z.col_ptrs[c]) += z.col_ptrs[c - 1]; | | access::rw(z.col_ptrs[c]) += z.col_ptrs[c - 1]; | |
| | | | |
| skipping to change at line 968 | | skipping to change at line 968 | |
| SpMat<eT>::operator+=(const subview<eT>& x) | | SpMat<eT>::operator+=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition
"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition
"); | |
| | | | |
| // Loop over every element. This could probably be written in a more | | // Loop over every element. This could probably be written in a more | |
| // efficient way, by calculating the number of nonzero elements the outpu
t | | // efficient way, by calculating the number of nonzero elements the outpu
t | |
| // matrix will have, allocating the memory correctly, and then filling th
e | | // matrix will have, allocating the memory correctly, and then filling th
e | |
| // matrix correctly. However... for now, this works okay. | | // matrix correctly. However... for now, this works okay. | |
|
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | for(uword col = 0; col < n_cols; ++col) | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | { | |
|
| at(lrow, lcol) += x.at(lrow, lcol); | | for(uword row = 0; row < n_rows; ++row) | |
| | | { | |
| | | at(row, col) += x.at(row, col); | |
| | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator-=(const subview<eT>& x) | | SpMat<eT>::operator-=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract
ion"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract
ion"); | |
| | | | |
| // Loop over every element. | | // Loop over every element. | |
|
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | for(uword col = 0; col < n_cols; ++col) | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | { | |
|
| at(lrow, lcol) -= x.at(lrow, lcol); | | for(uword row = 0; row < n_rows; ++row) | |
| | | { | |
| | | at(row, col) -= x.at(row, col); | |
| | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator*=(const subview<eT>& y) | | SpMat<eT>::operator*=(const subview<eT>& y) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_mul_size(n_rows, n_cols, y.n_rows, y.n_cols, "matrix mu
ltiplication"); | | arma_debug_assert_mul_size(n_rows, n_cols, y.n_rows, y.n_cols, "matrix mu
ltiplication"); | |
| | | | |
| SpMat<eT> z(n_rows, y.n_cols); | | SpMat<eT> z(n_rows, y.n_cols); | |
| | | | |
| // Performed in the same fashion as operator*=(SpMat). | | // Performed in the same fashion as operator*=(SpMat). | |
| for (const_row_iterator x_row_it = begin_row(); x_row_it.pos() < n_nonzer
o; ++x_row_it) | | for (const_row_iterator x_row_it = begin_row(); x_row_it.pos() < n_nonzer
o; ++x_row_it) | |
| { | | { | |
|
| for (uword lcol = 0; lcol < y.n_cols; ++lcol) | | for (uword col = 0; col < y.n_cols; ++col) | |
| { | | { | |
| // At this moment in the loop, we are calculating anything that is co
ntributed to by *x_row_it and *y_col_it. | | // At this moment in the loop, we are calculating anything that is co
ntributed to by *x_row_it and *y_col_it. | |
| // Given that our position is x_ab and y_bc, there will only be a con
tribution if x.col == y.row, and that | | // Given that our position is x_ab and y_bc, there will only be a con
tribution if x.col == y.row, and that | |
| // contribution will be in location z_ac. | | // contribution will be in location z_ac. | |
|
| z.at(x_row_it.row, lcol) += (*x_row_it) * y.at(x_row_it.col, lcol); | | z.at(x_row_it.row, col) += (*x_row_it) * y.at(x_row_it.col, col); | |
| } | | } | |
| } | | } | |
| | | | |
| steal_mem(z); | | steal_mem(z); | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator%=(const subview<eT>& x) | | SpMat<eT>::operator%=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | |
| | | | |
| // Loop over every element. | | // Loop over every element. | |
|
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | for(uword col = 0; col < n_cols; ++col) | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | { | |
|
| at(lrow, lcol) *= x.at(lrow, lcol); | | for(uword row = 0; row < n_rows; ++row) | |
| | | { | |
| | | at(row, col) *= x.at(row, col); | |
| | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator/=(const subview<eT>& x) | | SpMat<eT>::operator/=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise division"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise division"); | |
| | | | |
| // Loop over every element. | | // Loop over every element. | |
|
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | for(uword col = 0; col < n_cols; ++col) | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | { | |
|
| at(lrow, lcol) /= x.at(lrow, lcol); | | for(uword row = 0; row < n_rows; ++row) | |
| | | { | |
| | | at(row, col) /= x.at(row, col); | |
| | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1, typename spop_type> | | template<typename T1, typename spop_type> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X) | | SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X) | |
| : n_rows(0) | | : n_rows(0) | |
| | | | |
| skipping to change at line 1562 | | skipping to change at line 1570 | |
| { | | { | |
| return; | | return; | |
| } | | } | |
| | | | |
| // The easier way to do this, instead of collecting all the elements in o
ne row and then swapping with the other, will be | | // The easier way to do this, instead of collecting all the elements in o
ne row and then swapping with the other, will be | |
| // to iterate over each column of the matrix (since we store in column-ma
jor format) and then swap the two elements in the two rows at that time. | | // to iterate over each column of the matrix (since we store in column-ma
jor format) and then swap the two elements in the two rows at that time. | |
| // We will try to avoid using the at() call since it is expensive, instea
d preferring to use an iterator to track our position. | | // We will try to avoid using the at() call since it is expensive, instea
d preferring to use an iterator to track our position. | |
| uword col1 = (in_row1 < in_row2) ? in_row1 : in_row2; | | uword col1 = (in_row1 < in_row2) ? in_row1 : in_row2; | |
| uword col2 = (in_row1 < in_row2) ? in_row2 : in_row1; | | uword col2 = (in_row1 < in_row2) ? in_row2 : in_row1; | |
| | | | |
|
| for (uword lcol = 0; lcol < n_cols; lcol++) | | for (uword col = 0; col < n_cols; col++) | |
| { | | { | |
| // If there is nothing in this column we can ignore it. | | // If there is nothing in this column we can ignore it. | |
|
| if (col_ptrs[lcol] == col_ptrs[lcol + 1]) | | if (col_ptrs[col] == col_ptrs[col + 1]) | |
| { | | { | |
| continue; | | continue; | |
| } | | } | |
| | | | |
| // These will represent the positions of the items themselves. | | // These will represent the positions of the items themselves. | |
| uword loc1 = n_nonzero + 1; | | uword loc1 = n_nonzero + 1; | |
| uword loc2 = n_nonzero + 1; | | uword loc2 = n_nonzero + 1; | |
| | | | |
|
| for (uword search_pos = col_ptrs[lcol]; search_pos < col_ptrs[lcol + 1]
; search_pos++) | | for (uword search_pos = col_ptrs[col]; search_pos < col_ptrs[col + 1];
search_pos++) | |
| { | | { | |
| if (row_indices[search_pos] == col1) | | if (row_indices[search_pos] == col1) | |
| { | | { | |
| loc1 = search_pos; | | loc1 = search_pos; | |
| } | | } | |
| | | | |
| if (row_indices[search_pos] == col2) | | if (row_indices[search_pos] == col2) | |
| { | | { | |
| loc2 = search_pos; | | loc2 = search_pos; | |
| break; // No need to look any further. | | break; // No need to look any further. | |
| | | | |
| skipping to change at line 1601 | | skipping to change at line 1609 | |
| { | | { | |
| // This is an easy case: just swap the values. No index modifying ne
cessary. | | // This is an easy case: just swap the values. No index modifying ne
cessary. | |
| eT tmp = values[loc1]; | | eT tmp = values[loc1]; | |
| access::rw(values[loc1]) = values[loc2]; | | access::rw(values[loc1]) = values[loc2]; | |
| access::rw(values[loc2]) = tmp; | | access::rw(values[loc2]) = tmp; | |
| } | | } | |
| else if (loc1 != (n_nonzero + 1)) // We only found loc1 and not loc2. | | else if (loc1 != (n_nonzero + 1)) // We only found loc1 and not loc2. | |
| { | | { | |
| // We need to find the correct place to move our value to. It will b
e forward (not backwards) because in_row2 > in_row1. | | // We need to find the correct place to move our value to. It will b
e forward (not backwards) because in_row2 > in_row1. | |
| // Each iteration of the loop swaps the current value (loc1) with (lo
c1 + 1); in this manner we move our value down to where it should be. | | // Each iteration of the loop swaps the current value (loc1) with (lo
c1 + 1); in this manner we move our value down to where it should be. | |
|
| while (((loc1 + 1) < col_ptrs[lcol + 1]) && (row_indices[loc1 + 1] <
in_row2)) | | while (((loc1 + 1) < col_ptrs[col + 1]) && (row_indices[loc1 + 1] < i
n_row2)) | |
| { | | { | |
| // Swap both the values and the indices. The column should not cha
nge. | | // Swap both the values and the indices. The column should not cha
nge. | |
| eT tmp = values[loc1]; | | eT tmp = values[loc1]; | |
| access::rw(values[loc1]) = values[loc1 + 1]; | | access::rw(values[loc1]) = values[loc1 + 1]; | |
| access::rw(values[loc1 + 1]) = tmp; | | access::rw(values[loc1 + 1]) = tmp; | |
| | | | |
| uword tmp_index = row_indices[loc1]; | | uword tmp_index = row_indices[loc1]; | |
| access::rw(row_indices[loc1]) = row_indices[loc1 + 1]; | | access::rw(row_indices[loc1]) = row_indices[loc1 + 1]; | |
| access::rw(row_indices[loc1 + 1]) = tmp_index; | | access::rw(row_indices[loc1 + 1]) = tmp_index; | |
| | | | |
| | | | |
| skipping to change at line 1623 | | skipping to change at line 1631 | |
| } | | } | |
| | | | |
| // Now set the row index correctly. | | // Now set the row index correctly. | |
| access::rw(row_indices[loc1]) = in_row2; | | access::rw(row_indices[loc1]) = in_row2; | |
| | | | |
| } | | } | |
| else if (loc2 != (n_nonzero + 1)) | | else if (loc2 != (n_nonzero + 1)) | |
| { | | { | |
| // We need to find the correct place to move our value to. It will b
e backwards (not forwards) because in_row1 < in_row2. | | // We need to find the correct place to move our value to. It will b
e backwards (not forwards) because in_row1 < in_row2. | |
| // Each iteration of the loop swaps the current value (loc2) with (lo
c2 - 1); in this manner we move our value up to where it should be. | | // Each iteration of the loop swaps the current value (loc2) with (lo
c2 - 1); in this manner we move our value up to where it should be. | |
|
| while (((loc2 - 1) >= col_ptrs[lcol]) && (row_indices[loc2 - 1] > in_
row1)) | | while (((loc2 - 1) >= col_ptrs[col]) && (row_indices[loc2 - 1] > in_r
ow1)) | |
| { | | { | |
| // Swap both the values and the indices. The column should not cha
nge. | | // Swap both the values and the indices. The column should not cha
nge. | |
| eT tmp = values[loc2]; | | eT tmp = values[loc2]; | |
| access::rw(values[loc2]) = values[loc2 - 1]; | | access::rw(values[loc2]) = values[loc2 - 1]; | |
| access::rw(values[loc2 - 1]) = tmp; | | access::rw(values[loc2 - 1]) = tmp; | |
| | | | |
| uword tmp_index = row_indices[loc2]; | | uword tmp_index = row_indices[loc2]; | |
| access::rw(row_indices[loc2]) = row_indices[loc2 - 1]; | | access::rw(row_indices[loc2]) = row_indices[loc2 - 1]; | |
| access::rw(row_indices[loc2 - 1]) = tmp_index; | | access::rw(row_indices[loc2 - 1]) = tmp_index; | |
| | | | |
| | | | |
| skipping to change at line 1656 | | skipping to change at line 1664 | |
| * Swap in_col1 with in_col2. | | * Swap in_col1 with in_col2. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::swap_cols(const uword in_col1, const uword in_col2) | | SpMat<eT>::swap_cols(const uword in_col1, const uword in_col2) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // slow but works | | // slow but works | |
|
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
|
| eT tmp = at(lrow, in_col1); | | eT tmp = at(row, in_col1); | |
| at(lrow, in_col1) = at(lrow, in_col2); | | at(row, in_col1) = at(row, in_col2); | |
| at(lrow, in_col2) = tmp; | | at(row, in_col2) = tmp; | |
| } | | } | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Remove the row row_num. | | * Remove the row row_num. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::shed_row(const uword row_num) | | SpMat<eT>::shed_row(const uword row_num) | |
| | | | |
| skipping to change at line 1718 | | skipping to change at line 1726 | |
| uword i, j; | | uword i, j; | |
| // Store the length of values | | // Store the length of values | |
| uword vlength = n_nonzero; | | uword vlength = n_nonzero; | |
| // Store the length of col_ptrs | | // Store the length of col_ptrs | |
| uword clength = n_cols + 1; | | uword clength = n_cols + 1; | |
| | | | |
| // This is O(n * n_cols) and inplace, there may be a faster way, though. | | // This is O(n * n_cols) and inplace, there may be a faster way, though. | |
| for (i = 0, j = 0; i < vlength; ++i) | | for (i = 0, j = 0; i < vlength; ++i) | |
| { | | { | |
| // Store the row of the ith element. | | // Store the row of the ith element. | |
|
| const uword lrow = row_indices[i]; | | const uword row = row_indices[i]; | |
| // Is the ith element in the range of rows we want to remove? | | // Is the ith element in the range of rows we want to remove? | |
|
| if (lrow >= in_row1 && lrow <= in_row2) | | if (row >= in_row1 && row <= in_row2) | |
| { | | { | |
| // Increment our "removed elements" counter. | | // Increment our "removed elements" counter. | |
| ++j; | | ++j; | |
| | | | |
| // Adjust the values of col_ptrs each time we remove an element. | | // Adjust the values of col_ptrs each time we remove an element. | |
| // Basically, the length of one column reduces by one, and everything
to | | // Basically, the length of one column reduces by one, and everything
to | |
| // its right gets reduced by one to represent all the elements being | | // its right gets reduced by one to represent all the elements being | |
| // shifted to the left by one. | | // shifted to the left by one. | |
| for(uword k = 0; k < clength; ++k) | | for(uword k = 0; k < clength; ++k) | |
| { | | { | |
| | | | |
| skipping to change at line 1744 | | skipping to change at line 1752 | |
| } | | } | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // We shift the element we checked to the left by how many elements | | // We shift the element we checked to the left by how many elements | |
| // we have removed. | | // we have removed. | |
| // j = 0 until we remove the first element. | | // j = 0 until we remove the first element. | |
| if (j != 0) | | if (j != 0) | |
| { | | { | |
|
| access::rw(row_indices[i - j]) = (lrow > in_row2) ? (lrow - (in_row
2 - in_row1 + 1)) : lrow; | | access::rw(row_indices[i - j]) = (row > in_row2) ? (row - (in_row2
- in_row1 + 1)) : row; | |
| access::rw(values[i - j]) = values[i]; | | access::rw(values[i - j]) = values[i]; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| // j is the number of elements removed. | | // j is the number of elements removed. | |
| | | | |
| // Shrink the vectors. This will copy the memory. | | // Shrink the vectors. This will copy the memory. | |
| mem_resize(n_nonzero - j); | | mem_resize(n_nonzero - j); | |
| | | | |
| | | | |
| skipping to change at line 2750 | | skipping to change at line 2758 | |
| // paranoia, but better be safe than sorry | | // paranoia, but better be safe than sorry | |
| if( (index_left < index_new) && (index_new < index_right) ) | | if( (index_left < index_new) && (index_new < index_right) ) | |
| { | | { | |
| indices[i] = index_new; | | indices[i] = index_new; | |
| } | | } | |
| } | | } | |
| | | | |
| uword cur_index = 0; | | uword cur_index = 0; | |
| uword count = 0; | | uword count = 0; | |
| | | | |
|
| for(uword lcol = 0; lcol < in_cols; ++lcol) | | for(uword col = 0; col < in_cols; ++col) | |
| for(uword lrow = 0; lrow < in_rows; ++lrow) | | for(uword row = 0; row < in_rows; ++row) | |
| { | | { | |
| if(count == indices[cur_index]) | | if(count == indices[cur_index]) | |
| { | | { | |
|
| access::rw(row_indices[cur_index]) = lrow; | | access::rw(row_indices[cur_index]) = row; | |
| access::rw(col_ptrs[lcol + 1])++; | | access::rw(col_ptrs[col + 1])++; | |
| ++cur_index; | | ++cur_index; | |
| } | | } | |
| | | | |
| ++count; | | ++count; | |
| } | | } | |
| | | | |
| if(cur_index != n_nonzero) | | if(cur_index != n_nonzero) | |
| { | | { | |
| // Fix size to correct size. | | // Fix size to correct size. | |
| mem_resize(cur_index); | | mem_resize(cur_index); | |
| } | | } | |
| | | | |
| // Sum column pointers. | | // Sum column pointers. | |
|
| for(uword lcol = 1; lcol <= in_cols; ++lcol) | | for(uword col = 1; col <= in_cols; ++col) | |
| { | | { | |
|
| access::rw(col_ptrs[lcol]) += col_ptrs[lcol - 1]; | | access::rw(col_ptrs[col]) += col_ptrs[col - 1]; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::sprandn(const uword in_rows, const uword in_cols, const double d
ensity) | | SpMat<eT>::sprandn(const uword in_rows, const uword in_cols, const double d
ensity) | |
| { | | { | |
| | | | |
| skipping to change at line 2825 | | skipping to change at line 2833 | |
| // paranoia, but better be safe than sorry | | // paranoia, but better be safe than sorry | |
| if( (index_left < index_new) && (index_new < index_right) ) | | if( (index_left < index_new) && (index_new < index_right) ) | |
| { | | { | |
| indices[i] = index_new; | | indices[i] = index_new; | |
| } | | } | |
| } | | } | |
| | | | |
| uword cur_index = 0; | | uword cur_index = 0; | |
| uword count = 0; | | uword count = 0; | |
| | | | |
|
| for(uword lcol = 0; lcol < in_cols; ++lcol) | | for(uword col = 0; col < in_cols; ++col) | |
| for(uword lrow = 0; lrow < in_rows; ++lrow) | | for(uword row = 0; row < in_rows; ++row) | |
| { | | { | |
| if(count == indices[cur_index]) | | if(count == indices[cur_index]) | |
| { | | { | |
|
| access::rw(row_indices[cur_index]) = lrow; | | access::rw(row_indices[cur_index]) = row; | |
| access::rw(col_ptrs[lcol + 1])++; | | access::rw(col_ptrs[col + 1])++; | |
| ++cur_index; | | ++cur_index; | |
| } | | } | |
| | | | |
| ++count; | | ++count; | |
| } | | } | |
| | | | |
| if(cur_index != n_nonzero) | | if(cur_index != n_nonzero) | |
| { | | { | |
| // Fix size to correct size. | | // Fix size to correct size. | |
| mem_resize(cur_index); | | mem_resize(cur_index); | |
| } | | } | |
| | | | |
| // Sum column pointers. | | // Sum column pointers. | |
|
| for(uword lcol = 1; lcol <= in_cols; ++lcol) | | for(uword col = 1; col <= in_cols; ++col) | |
| { | | { | |
|
| access::rw(col_ptrs[lcol]) += col_ptrs[lcol - 1]; | | access::rw(col_ptrs[col]) += col_ptrs[col - 1]; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::reset() | | SpMat<eT>::reset() | |
| { | | { | |
| | | | |
| skipping to change at line 3466 | | skipping to change at line 3474 | |
| line_start = line_end + 1; | | line_start = line_end + 1; | |
| | | | |
| } | | } | |
| | | | |
| set_size(t_n_rows, t_n_cols); | | set_size(t_n_rows, t_n_cols); | |
| | | | |
| // Second time through will pick up all the values. | | // Second time through will pick up all the values. | |
| line_start = 0; | | line_start = 0; | |
| line_end = 0; | | line_end = 0; | |
| | | | |
|
| uword lrow = 0; | | uword row = 0; | |
| | | | |
| while (line_start < text.length()) | | while (line_start < text.length()) | |
| { | | { | |
| | | | |
| line_end = text.find(';', line_start); | | line_end = text.find(';', line_start); | |
| | | | |
| if (line_end == std::string::npos) | | if (line_end == std::string::npos) | |
| line_end = text.length() - 1; | | line_end = text.length() - 1; | |
| | | | |
| std::string::size_type line_len = line_end - line_start + 1; | | std::string::size_type line_len = line_end - line_start + 1; | |
| std::stringstream line_stream(text.substr(line_start, line_len)); | | std::stringstream line_stream(text.substr(line_start, line_len)); | |
| | | | |
|
| uword lcol = 0; | | uword col = 0; | |
| eT val; | | eT val; | |
| | | | |
| while (line_stream >> val) | | while (line_stream >> val) | |
| { | | { | |
| // Only add nonzero elements. | | // Only add nonzero elements. | |
| if (val != eT(0)) | | if (val != eT(0)) | |
| { | | { | |
|
| get_value(lrow, lcol) = val; | | get_value(row, col) = val; | |
| } | | } | |
| | | | |
|
| ++lcol; | | ++col; | |
| } | | } | |
| | | | |
|
| ++lrow; | | ++row; | |
| line_start = line_end + 1; | | line_start = line_end + 1; | |
| | | | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Copy from another matrix. | | * Copy from another matrix. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 3568 | | skipping to change at line 3576 | |
| const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero)
; | | const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero)
; | |
| | | | |
| if(n_alloc < new_n_nonzero) | | if(n_alloc < new_n_nonzero) | |
| { | | { | |
| eT* new_values = memory::acquire_chunked<eT> (new_n_nonze
ro + 1); | | eT* new_values = memory::acquire_chunked<eT> (new_n_nonze
ro + 1); | |
| uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonze
ro + 1); | | uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonze
ro + 1); | |
| | | | |
| if(n_nonzero > 0) | | if(n_nonzero > 0) | |
| { | | { | |
| // Copy old elements. | | // Copy old elements. | |
|
| uword copy_len = std::min(n_nonzero, new_n_nonzero); | | uword copy_size = std::min(n_nonzero, new_n_nonzero); | |
| | | | |
|
| arrayops::copy(new_values, values, copy_len); | | arrayops::copy(new_values, values, copy_size); | |
| arrayops::copy(new_row_indices, row_indices, copy_len); | | arrayops::copy(new_row_indices, row_indices, copy_size); | |
| } | | } | |
| | | | |
| memory::release(values); | | memory::release(values); | |
| memory::release(row_indices); | | memory::release(row_indices); | |
| | | | |
| access::rw(values) = new_values; | | access::rw(values) = new_values; | |
| access::rw(row_indices) = new_row_indices; | | access::rw(row_indices) = new_row_indices; | |
| } | | } | |
| | | | |
| // Set the "fake end" of the matrix by setting the last value and row | | // Set the "fake end" of the matrix by setting the last value and row | |
| | | | |
| skipping to change at line 3900 | | skipping to change at line 3908 | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_hot | | arma_hot | |
| arma_warn_unused | | arma_warn_unused | |
| SpValProxy<SpMat<eT> > | | SpValProxy<SpMat<eT> > | |
| SpMat<eT>::get_value(const uword i) | | SpMat<eT>::get_value(const uword i) | |
| { | | { | |
| // First convert to the actual location. | | // First convert to the actual location. | |
|
| uword lcol = i / n_rows; // Integer division. | | uword col = i / n_rows; // Integer division. | |
| uword lrow = i % n_rows; | | uword row = i % n_rows; | |
| | | | |
|
| return get_value(lrow, lcol); | | return get_value(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_hot | | arma_hot | |
| arma_warn_unused | | arma_warn_unused | |
| eT | | eT | |
| SpMat<eT>::get_value(const uword i) const | | SpMat<eT>::get_value(const uword i) const | |
| { | | { | |
| // First convert to the actual location. | | // First convert to the actual location. | |
|
| uword lcol = i / n_rows; // Integer division. | | uword col = i / n_rows; // Integer division. | |
| uword lrow = i % n_rows; | | uword row = i % n_rows; | |
| | | | |
|
| return get_value(lrow, lcol); | | return get_value(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_hot | | arma_hot | |
| arma_warn_unused | | arma_warn_unused | |
| SpValProxy<SpMat<eT> > | | SpValProxy<SpMat<eT> > | |
| SpMat<eT>::get_value(const uword in_row, const uword in_col) | | SpMat<eT>::get_value(const uword in_row, const uword in_col) | |
| { | | { | |
| const uword colptr = col_ptrs[in_col]; | | const uword colptr = col_ptrs[in_col]; | |
| | | | |
| skipping to change at line 3996 | | skipping to change at line 4004 | |
| * Given the index representing which of the nonzero values this is, return
its | | * Given the index representing which of the nonzero values this is, return
its | |
| * actual location, either in row/col or just the index. | | * actual location, either in row/col or just the index. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| arma_inline | | arma_inline | |
| arma_warn_unused | | arma_warn_unused | |
| uword | | uword | |
| SpMat<eT>::get_position(const uword i) const | | SpMat<eT>::get_position(const uword i) const | |
| { | | { | |
|
| uword lrow, lcol; | | uword row, col; | |
| | | | |
|
| get_position(i, lrow, lcol); | | get_position(i, row, col); | |
| | | | |
| // Assemble the row/col into the element's location in the matrix. | | // Assemble the row/col into the element's location in the matrix. | |
|
| return (lrow + n_rows * lcol); | | return (row + n_rows * col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| arma_inline | | arma_inline | |
| void | | void | |
| SpMat<eT>::get_position(const uword i, uword& row_of_i, uword& col_of_i) co
nst | | SpMat<eT>::get_position(const uword i, uword& row_of_i, uword& col_of_i) co
nst | |
| { | | { | |
| arma_debug_check((i >= n_nonzero), "SpMat::get_position(): index out of b
ounds"); | | arma_debug_check((i >= n_nonzero), "SpMat::get_position(): index out of b
ounds"); | |
| | | | |
| | | | |
End of changes. 45 change blocks. |
| 59 lines changed or deleted | | 67 lines changed or added | |
|
| SpSubview_iterators_meat.hpp | | SpSubview_iterators_meat.hpp | |
| | | | |
| skipping to change at line 33 | | skipping to change at line 33 | |
| : M(in_M) | | : M(in_M) | |
| , internal_col(0) | | , internal_col(0) | |
| , internal_pos(0) | | , internal_pos(0) | |
| , skip_pos(0) | | , skip_pos(0) | |
| { | | { | |
| // Technically this iterator is invalid (it may not point to a real eleme
nt). | | // Technically this iterator is invalid (it may not point to a real eleme
nt). | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| SpSubview<eT>::iterator_base::iterator_base(const SpSubview<eT>& in_M, cons
t uword in_col, const uword in_pos, const uword in_skip_pos) | | SpSubview<eT>::iterator_base::iterator_base(const SpSubview<eT>& in_M, cons
t uword col, const uword pos, const uword skip_pos) | |
| : M(in_M) | | : M(in_M) | |
|
| , internal_col(in_col) | | , internal_col(col) | |
| , internal_pos(in_pos) | | , internal_pos(pos) | |
| , skip_pos (in_skip_pos) | | , skip_pos(skip_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| eT | | eT | |
| SpSubview<eT>::iterator_base::operator*() const | | SpSubview<eT>::iterator_base::operator*() const | |
| { | | { | |
| return M.m.values[internal_pos + skip_pos]; | | return M.m.values[internal_pos + skip_pos]; | |
| | | | |
| skipping to change at line 63 | | skipping to change at line 63 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, co
nst uword initial_pos) | | SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, co
nst uword initial_pos) | |
| : iterator_base(in_M, 0, initial_pos, 0) | | : iterator_base(in_M, 0, initial_pos, 0) | |
| { | | { | |
| // Corner case for empty subviews. | | // Corner case for empty subviews. | |
| if(in_M.n_nonzero == 0) | | if(in_M.n_nonzero == 0) | |
| { | | { | |
| iterator_base::internal_col = in_M.n_cols; | | iterator_base::internal_col = in_M.n_cols; | |
|
| iterator_base::skip_pos = in_M.m.n_nonzero; | | iterator_base::skip_pos = in_M.m.n_nonzero; | |
| return; | | return; | |
| } | | } | |
| | | | |
| // Figure out the row and column of the position. | | // Figure out the row and column of the position. | |
|
| // lskip_pos holds the number of values which aren't part of this subview
. | | // skip_pos holds the number of values which aren't part of this subview. | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_rows = iterator_base::M.n_rows; | | const uword n_rows = iterator_base::M.n_rows; | |
| const uword ln_cols = iterator_base::M.n_cols; | | const uword n_cols = iterator_base::M.n_cols; | |
| | | | |
|
| uword cur_pos = 0; // off by one because we might be searching for pos | | uword cur_pos = 0; // off by one because we might be searching for pos 0 | |
| 0 | | uword skip_pos = iterator_base::M.m.col_ptrs[aux_col]; | |
| uword lskip_pos = iterator_base::M.m.col_ptrs[aux_col]; | | uword cur_col = 0; | |
| uword cur_col = 0; | | | |
| | | | |
| while(cur_pos < (iterator_base::internal_pos + 1)) | | while(cur_pos < (iterator_base::internal_pos + 1)) | |
| { | | { | |
| // Have we stepped forward a column (or multiple columns)? | | // Have we stepped forward a column (or multiple columns)? | |
|
| while(((lskip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + a
ux_col + 1]) && (cur_col < ln_cols)) | | while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + au
x_col + 1]) && (cur_col < n_cols)) | |
| { | | { | |
| ++cur_col; | | ++cur_col; | |
| } | | } | |
| | | | |
| // See if the current position is in the subview. | | // See if the current position is in the subview. | |
|
| const uword row_index = iterator_base::M.m.row_indices[cur_pos + lskip_
pos]; | | const uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_p
os]; | |
| if(row_index < aux_row) | | if(row_index < aux_row) | |
| { | | { | |
|
| ++lskip_pos; // not valid | | ++skip_pos; // not valid | |
| } | | } | |
|
| else if(row_index < (aux_row + ln_rows)) | | else if(row_index < (aux_row + n_rows)) | |
| { | | { | |
| ++cur_pos; // valid, in the subview | | ++cur_pos; // valid, in the subview | |
| } | | } | |
| else | | else | |
| { | | { | |
| // skip to end of column | | // skip to end of column | |
| const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_c
ol + 1]; | | const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_c
ol + 1]; | |
|
| lskip_pos += (next_colptr - (cur_pos + lskip_pos)); | | skip_pos += (next_colptr - (cur_pos + skip_pos)); | |
| } | | } | |
| } | | } | |
| | | | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
|
| iterator_base::skip_pos = lskip_pos; | | iterator_base::skip_pos = skip_pos; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, co
nst uword in_row, const uword in_col) | | SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, co
nst uword in_row, const uword in_col) | |
| : iterator_base(in_M, in_col, 0, 0) | | : iterator_base(in_M, in_col, 0, 0) | |
| { | | { | |
| // Corner case for empty subviews. | | // Corner case for empty subviews. | |
| if(in_M.n_nonzero == 0) | | if(in_M.n_nonzero == 0) | |
| { | | { | |
| // We must be at the last position. | | // We must be at the last position. | |
| iterator_base::internal_col = in_M.n_cols; | | iterator_base::internal_col = in_M.n_cols; | |
| iterator_base::skip_pos = in_M.m.n_nonzero; | | iterator_base::skip_pos = in_M.m.n_nonzero; | |
| return; | | return; | |
| } | | } | |
| | | | |
| // We have a destination we want to be just after, but don't know what po
sition that is. | | // We have a destination we want to be just after, but don't know what po
sition that is. | |
| // Because we have to count the points in this subview and not in this su
bview, this becomes a little difficult and slow. | | // Because we have to count the points in this subview and not in this su
bview, this becomes a little difficult and slow. | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_rows = iterator_base::M.n_rows; | | const uword n_rows = iterator_base::M.n_rows; | |
| const uword ln_cols = iterator_base::M.n_cols; | | const uword n_cols = iterator_base::M.n_cols; | |
| | | | |
| uword cur_pos = 0; | | uword cur_pos = 0; | |
| uword skip_pos = iterator_base::M.m.col_ptrs[aux_col]; | | uword skip_pos = iterator_base::M.m.col_ptrs[aux_col]; | |
| uword cur_col = 0; | | uword cur_col = 0; | |
| | | | |
| while(cur_col < in_col) | | while(cur_col < in_col) | |
| { | | { | |
| // See if the current position is in the subview. | | // See if the current position is in the subview. | |
| const uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_p
os]; | | const uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_p
os]; | |
| if(row_index < aux_row) | | if(row_index < aux_row) | |
| { | | { | |
| ++skip_pos; | | ++skip_pos; | |
| } | | } | |
|
| else if(row_index < (aux_row + ln_rows)) | | else if(row_index < (aux_row + n_rows)) | |
| { | | { | |
| ++cur_pos; | | ++cur_pos; | |
| } | | } | |
| else | | else | |
| { | | { | |
| // skip to end of column | | // skip to end of column | |
| const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_c
ol + 1]; | | const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_c
ol + 1]; | |
| skip_pos += (next_colptr - (cur_pos + skip_pos)); | | skip_pos += (next_colptr - (cur_pos + skip_pos)); | |
| } | | } | |
| | | | |
| // Have we stepped forward a column (or multiple columns)? | | // Have we stepped forward a column (or multiple columns)? | |
|
| while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + au
x_col + 1]) && (cur_col < ln_cols)) | | while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + au
x_col + 1]) && (cur_col < n_cols)) | |
| { | | { | |
| ++cur_col; | | ++cur_col; | |
| } | | } | |
| } | | } | |
| | | | |
| // Now we are either on the right column or ahead of it. | | // Now we are either on the right column or ahead of it. | |
| if(cur_col == in_col) | | if(cur_col == in_col) | |
| { | | { | |
| // We have to find the right row index. | | // We have to find the right row index. | |
| uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | | uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
| | | | |
| skipping to change at line 176 | | skipping to change at line 176 | |
| if(row_index < aux_row) | | if(row_index < aux_row) | |
| { | | { | |
| ++skip_pos; | | ++skip_pos; | |
| } | | } | |
| else | | else | |
| { | | { | |
| ++cur_pos; | | ++cur_pos; | |
| } | | } | |
| | | | |
| // Ensure we didn't step forward a column; if we did, we need to stop
. | | // Ensure we didn't step forward a column; if we did, we need to stop
. | |
|
| while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col +
aux_col + 1]) && (cur_col < ln_cols)) | | while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col +
aux_col + 1]) && (cur_col < n_cols)) | |
| { | | { | |
| ++cur_col; | | ++cur_col; | |
| } | | } | |
| | | | |
| if(cur_col != in_col) | | if(cur_col != in_col) | |
| { | | { | |
| break; | | break; | |
| } | | } | |
| | | | |
| row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | | row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
| | | | |
| skipping to change at line 198 | | skipping to change at line 198 | |
| } | | } | |
| | | | |
| // Now we need to find the next valid position in the subview. | | // Now we need to find the next valid position in the subview. | |
| uword row_index; | | uword row_index; | |
| while(true) | | while(true) | |
| { | | { | |
| const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | | const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | |
| row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | | row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
| | | | |
| // Are we at the last position? | | // Are we at the last position? | |
|
| if(cur_col >= ln_cols) | | if(cur_col >= n_cols) | |
| { | | { | |
|
| cur_col = ln_cols; | | cur_col = n_cols; | |
| // Make sure we will be pointing at the last element in the parent ma
trix. | | // Make sure we will be pointing at the last element in the parent ma
trix. | |
| skip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero; | | skip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero; | |
| break; | | break; | |
| } | | } | |
| | | | |
| if(row_index < aux_row) | | if(row_index < aux_row) | |
| { | | { | |
| ++skip_pos; | | ++skip_pos; | |
| } | | } | |
|
| else if(row_index < (aux_row + ln_rows)) | | else if(row_index < (aux_row + n_rows)) | |
| { | | { | |
| break; // found | | break; // found | |
| } | | } | |
| else | | else | |
| { | | { | |
| skip_pos += (next_colptr - (cur_pos + skip_pos)); | | skip_pos += (next_colptr - (cur_pos + skip_pos)); | |
| } | | } | |
| | | | |
| // Did we move any columns? | | // Did we move any columns? | |
|
| while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + au
x_col + 1]) && (cur_col < ln_cols)) | | while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + au
x_col + 1]) && (cur_col < n_cols)) | |
| { | | { | |
| ++cur_col; | | ++cur_col; | |
| } | | } | |
| } | | } | |
| | | | |
| // It is possible we have moved another column. | | // It is possible we have moved another column. | |
|
| while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_
col + 1]) && (cur_col < ln_cols)) | | while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_
col + 1]) && (cur_col < n_cols)) | |
| { | | { | |
| ++cur_col; | | ++cur_col; | |
| } | | } | |
| | | | |
| iterator_base::internal_pos = cur_pos; | | iterator_base::internal_pos = cur_pos; | |
|
| iterator_base::skip_pos = skip_pos; | | iterator_base::skip_pos = skip_pos; | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, uw | | SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, uw | |
| ord in_row, uword in_col, uword in_pos, uword in_skip_pos) | | ord in_row, uword in_col, uword in_pos, uword skip_pos) | |
| : iterator_base(in_M, in_col, in_pos, in_skip_pos) | | : iterator_base(in_M, in_col, in_pos, skip_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpSubview<eT>::const_iterator::const_iterator(const const_iterator& other) | | SpSubview<eT>::const_iterator::const_iterator(const const_iterator& other) | |
| : iterator_base(other.M, other.internal_col, other.internal_pos, other.sk
ip_pos) | | : iterator_base(other.M, other.internal_col, other.internal_pos, other.sk
ip_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::const_iterator& | | typename SpSubview<eT>::const_iterator& | |
| SpSubview<eT>::const_iterator::operator++() | | SpSubview<eT>::const_iterator::operator++() | |
| { | | { | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_rows = iterator_base::M.n_rows; | | const uword n_rows = iterator_base::M.n_rows; | |
| const uword ln_cols = iterator_base::M.n_cols; | | const uword n_cols = iterator_base::M.n_cols; | |
| | | | |
|
| uword cur_col = iterator_base::internal_col; | | uword cur_col = iterator_base::internal_col; | |
| uword cur_pos = iterator_base::internal_pos + 1; | | uword cur_pos = iterator_base::internal_pos + 1; | |
| uword lskip_pos = iterator_base::skip_pos; | | uword skip_pos = iterator_base::skip_pos; | |
| uword row_index; | | uword row_index; | |
| | | | |
| while(true) | | while(true) | |
| { | | { | |
| const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | | const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | |
|
| row_index = iterator_base::M.m.row_indices[cur_pos + lskip_pos]; | | row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
| | | | |
| // Did we move any columns? | | // Did we move any columns? | |
|
| while((cur_col < ln_cols) && ((lskip_pos + cur_pos) >= iterator_base::M
.m.col_ptrs[cur_col + aux_col + 1])) | | while((cur_col < n_cols) && ((skip_pos + cur_pos) >= iterator_base::M.m
.col_ptrs[cur_col + aux_col + 1])) | |
| { | | { | |
| ++cur_col; | | ++cur_col; | |
| } | | } | |
| | | | |
| // Are we at the last position? | | // Are we at the last position? | |
|
| if(cur_col >= ln_cols) | | if(cur_col >= n_cols) | |
| { | | { | |
|
| cur_col = ln_cols; | | cur_col = n_cols; | |
| // Make sure we will be pointing at the last element in the parent ma
trix. | | // Make sure we will be pointing at the last element in the parent ma
trix. | |
|
| lskip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero
; | | skip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero; | |
| break; | | break; | |
| } | | } | |
| | | | |
| if(row_index < aux_row) | | if(row_index < aux_row) | |
| { | | { | |
|
| ++lskip_pos; | | ++skip_pos; | |
| } | | } | |
|
| else if(row_index < (aux_row + ln_rows)) | | else if(row_index < (aux_row + n_rows)) | |
| { | | { | |
| break; // found | | break; // found | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| lskip_pos += (next_colptr - (cur_pos + lskip_pos)); | | skip_pos += (next_colptr - (cur_pos + skip_pos)); | |
| } | | } | |
| } | | } | |
| | | | |
| iterator_base::internal_pos = cur_pos; | | iterator_base::internal_pos = cur_pos; | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
|
| iterator_base::skip_pos = lskip_pos; | | iterator_base::skip_pos = skip_pos; | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::const_iterator | | typename SpSubview<eT>::const_iterator | |
| SpSubview<eT>::const_iterator::operator++(int) | | SpSubview<eT>::const_iterator::operator++(int) | |
| { | | { | |
| typename SpSubview<eT>::const_iterator tmp(*this); | | typename SpSubview<eT>::const_iterator tmp(*this); | |
| | | | |
| skipping to change at line 328 | | skipping to change at line 328 | |
| return tmp; | | return tmp; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::const_iterator& | | typename SpSubview<eT>::const_iterator& | |
| SpSubview<eT>::const_iterator::operator--() | | SpSubview<eT>::const_iterator::operator--() | |
| { | | { | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_rows = iterator_base::M.n_rows; | | const uword n_rows = iterator_base::M.n_rows; | |
| | | | |
|
| uword cur_col = iterator_base::internal_col; | | uword cur_col = iterator_base::internal_col; | |
| uword cur_pos = iterator_base::internal_pos - 1; | | uword cur_pos = iterator_base::internal_pos - 1; | |
| uword skip_pos = iterator_base::skip_pos; | | uword skip_pos = iterator_base::skip_pos; | |
| | | | |
| // Special condition for end of iterator. | | // Special condition for end of iterator. | |
| if((skip_pos + cur_pos + 1) == iterator_base::M.m.n_nonzero) | | if((skip_pos + cur_pos + 1) == iterator_base::M.m.n_nonzero) | |
| { | | { | |
| // We are at the last element. So we need to set skip_pos back to what
it | | // We are at the last element. So we need to set skip_pos back to what
it | |
| // would be if we didn't manually modify it back in operator++(). | | // would be if we didn't manually modify it back in operator++(). | |
| skip_pos = iterator_base::M.m.col_ptrs[cur_col + aux_col] - iterator_ba
se::internal_pos; | | skip_pos = iterator_base::M.m.col_ptrs[cur_col + aux_col] - iterator_ba
se::internal_pos; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 359 | | skipping to change at line 359 | |
| // Did we move back any columns? | | // Did we move back any columns? | |
| while((skip_pos + cur_pos) < iterator_base::M.m.col_ptrs[cur_col + aux_
col]) | | while((skip_pos + cur_pos) < iterator_base::M.m.col_ptrs[cur_col + aux_
col]) | |
| { | | { | |
| --cur_col; | | --cur_col; | |
| } | | } | |
| | | | |
| if(row_index < aux_row) | | if(row_index < aux_row) | |
| { | | { | |
| skip_pos -= (colptr - (cur_pos + skip_pos) + 1); | | skip_pos -= (colptr - (cur_pos + skip_pos) + 1); | |
| } | | } | |
|
| else if(row_index < (aux_row + ln_rows)) | | else if(row_index < (aux_row + n_rows)) | |
| { | | { | |
| break; // found | | break; // found | |
| } | | } | |
| else | | else | |
| { | | { | |
| --skip_pos; | | --skip_pos; | |
| } | | } | |
| } | | } | |
| | | | |
| iterator_base::internal_pos = cur_pos; | | iterator_base::internal_pos = cur_pos; | |
|
| iterator_base::skip_pos = skip_pos; | | iterator_base::skip_pos = skip_pos; | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::const_iterator | | typename SpSubview<eT>::const_iterator | |
| SpSubview<eT>::const_iterator::operator--(int) | | SpSubview<eT>::const_iterator::operator--(int) | |
| { | | { | |
| | | | |
| skipping to change at line 532 | | skipping to change at line 532 | |
| if(in_M.n_nonzero == 0) | | if(in_M.n_nonzero == 0) | |
| { | | { | |
| iterator_base::internal_col = 0; | | iterator_base::internal_col = 0; | |
| internal_row = in_M.n_rows; | | internal_row = in_M.n_rows; | |
| iterator_base::skip_pos = in_M.m.n_nonzero; | | iterator_base::skip_pos = in_M.m.n_nonzero; | |
| return; | | return; | |
| } | | } | |
| | | | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_cols = iterator_base::M.n_cols; | | const uword n_cols = iterator_base::M.n_cols; | |
| | | | |
| // We don't know where the elements are in each row. What we will do is | | // We don't know where the elements are in each row. What we will do is | |
| // loop across all valid columns looking for elements in row 0 (and add t
o | | // loop across all valid columns looking for elements in row 0 (and add t
o | |
| // our sum), then in row 1, and so forth, until we get to the desired | | // our sum), then in row 1, and so forth, until we get to the desired | |
| // position. | | // position. | |
| uword cur_pos = -1; | | uword cur_pos = -1; | |
| uword cur_row = 0; | | uword cur_row = 0; | |
| uword cur_col = 0; | | uword cur_col = 0; | |
| | | | |
| while(true) | | while(true) | |
| | | | |
| skipping to change at line 574 | | skipping to change at line 574 | |
| // We are done with this column. Break to the column incrementing
code (directly below). | | // We are done with this column. Break to the column incrementing
code (directly below). | |
| break; | | break; | |
| } | | } | |
| else if(row_index > (cur_row + aux_row)) | | else if(row_index > (cur_row + aux_row)) | |
| { | | { | |
| break; // Can't be in this column. | | break; // Can't be in this column. | |
| } | | } | |
| } | | } | |
| | | | |
| cur_col++; // Done with the column. Move on. | | cur_col++; // Done with the column. Move on. | |
|
| if(cur_col == ln_cols) | | if(cur_col == n_cols) | |
| { | | { | |
| // Out of columns. Loop back to the beginning and look on the next r
ow. | | // Out of columns. Loop back to the beginning and look on the next r
ow. | |
| cur_col = 0; | | cur_col = 0; | |
| cur_row++; | | cur_row++; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 641 | | skipping to change at line 641 | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| // Otherwise, we need to search. | | // Otherwise, we need to search. | |
| uword cur_col = iterator_base::internal_col; | | uword cur_col = iterator_base::internal_col; | |
| uword cur_row = internal_row; | | uword cur_row = internal_row; | |
| | | | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_cols = iterator_base::M.n_cols; | | const uword n_cols = iterator_base::M.n_cols; | |
| | | | |
| while(true) | | while(true) | |
| { | | { | |
| // Increment the current column and see if we are on a new row. | | // Increment the current column and see if we are on a new row. | |
|
| if(++cur_col == ln_cols) | | if(++cur_col == n_cols) | |
| { | | { | |
| cur_col = 0; | | cur_col = 0; | |
| ++cur_row; | | ++cur_row; | |
| } | | } | |
| | | | |
| // Is there anything in this new column? | | // Is there anything in this new column? | |
| const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | | const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | |
| const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | | const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | |
| | | | |
| for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_
indices[ind] <= (cur_row + aux_row)); ++ind) | | for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_
indices[ind] <= (cur_row + aux_row)); ++ind) | |
| | | | |
| skipping to change at line 716 | | skipping to change at line 716 | |
| // } | | // } | |
| | | | |
| iterator_base::internal_pos--; | | iterator_base::internal_pos--; | |
| | | | |
| // We have to search backwards. | | // We have to search backwards. | |
| uword cur_col = iterator_base::internal_col; | | uword cur_col = iterator_base::internal_col; | |
| uword cur_row = internal_row; | | uword cur_row = internal_row; | |
| | | | |
| const uword aux_col = iterator_base::M.aux_col1; | | const uword aux_col = iterator_base::M.aux_col1; | |
| const uword aux_row = iterator_base::M.aux_row1; | | const uword aux_row = iterator_base::M.aux_row1; | |
|
| const uword ln_cols = iterator_base::M.n_cols; | | const uword n_cols = iterator_base::M.n_cols; | |
| | | | |
| while(true) | | while(true) | |
| { | | { | |
| // Decrement the current column and see if we are on a new row. | | // Decrement the current column and see if we are on a new row. | |
|
| if(--cur_col > ln_cols) | | if(--cur_col > n_cols) | |
| { | | { | |
|
| cur_col = ln_cols - 1; | | cur_col = n_cols - 1; | |
| cur_row--; | | cur_row--; | |
| } | | } | |
| | | | |
| // Is there anything in this new column? | | // Is there anything in this new column? | |
| const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | | const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | |
| const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | | const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col
+ 1]; | |
| | | | |
| for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_
indices[ind] <= (cur_row + aux_row)); ++ind) | | for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_
indices[ind] <= (cur_row + aux_row)); ++ind) | |
| { | | { | |
| const uword row_index = iterator_base::M.m.row_indices[ind]; | | const uword row_index = iterator_base::M.m.row_indices[ind]; | |
| | | | |
End of changes. 45 change blocks. |
| 58 lines changed or deleted | | 57 lines changed or added | |
|
| SpSubview_meat.hpp | | SpSubview_meat.hpp | |
| | | | |
| skipping to change at line 31 | | skipping to change at line 31 | |
| , aux_row1(in_row1) | | , aux_row1(in_row1) | |
| , aux_col1(in_col1) | | , aux_col1(in_col1) | |
| , n_rows(in_n_rows) | | , n_rows(in_n_rows) | |
| , n_cols(in_n_cols) | | , n_cols(in_n_cols) | |
| , n_elem(in_n_rows * in_n_cols) | | , n_elem(in_n_rows * in_n_cols) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // There must be a O(1) way to do this | | // There must be a O(1) way to do this | |
|
| uword lend = m.col_ptrs[in_col1 + in_n_cols]; | | uword end = m.col_ptrs[in_col1 + in_n_cols]; | |
| uword lend_row = in_row1 + in_n_rows; | | uword end_row = in_row1 + in_n_rows; | |
| uword count = 0; | | uword count = 0; | |
| | | | |
|
| for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) | | for(uword i = m.col_ptrs[in_col1]; i < end; ++i) | |
| { | | { | |
|
| if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row) | | if(m.row_indices[i] >= in_row1 && m.row_indices[i] < end_row) | |
| { | | { | |
| ++count; | | ++count; | |
| } | | } | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) = count; | | access::rw(n_nonzero) = count; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_inline | | arma_inline | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| , aux_row1(in_row1) | | , aux_row1(in_row1) | |
| , aux_col1(in_col1) | | , aux_col1(in_col1) | |
| , n_rows(in_n_rows) | | , n_rows(in_n_rows) | |
| , n_cols(in_n_cols) | | , n_cols(in_n_cols) | |
| , n_elem(in_n_rows * in_n_cols) | | , n_elem(in_n_rows * in_n_cols) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // There must be a O(1) way to do this | | // There must be a O(1) way to do this | |
|
| uword lend = m.col_ptrs[in_col1 + in_n_cols]; | | uword end = m.col_ptrs[in_col1 + in_n_cols]; | |
| uword lend_row = in_row1 + in_n_rows; | | uword end_row = in_row1 + in_n_rows; | |
| uword count = 0; | | uword count = 0; | |
| | | | |
|
| for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) | | for(uword i = m.col_ptrs[in_col1]; i < end; ++i) | |
| { | | { | |
|
| if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row) | | if(m.row_indices[i] >= in_row1 && m.row_indices[i] < end_row) | |
| { | | { | |
| ++count; | | ++count; | |
| } | | } | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) = count; | | access::rw(n_nonzero) = count; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 94 | | skipping to change at line 94 | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator+=(const eT val) | | SpSubview<eT>::operator+=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(val == eT(0)) | | if(val == eT(0)) | |
| { | | { | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| const uword lstart_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword lend_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | const uword start_col = aux_col1; | |
| const uword lstart_col = aux_col1; | | const uword end_col = aux_col1 + n_cols; | |
| const uword lend_col = aux_col1 + n_cols; | | | |
| | | | |
| const uword old_n_nonzero = m.n_nonzero; | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
| // iterate over our part of the sparse matrix | | // iterate over our part of the sparse matrix | |
|
| for(uword lcol = lstart_col; lcol < lend_col; ++lcol) | | for(uword col = start_col; col < end_col; ++col) | |
| for(uword lrow = lstart_row; lrow < lend_row; ++lrow) | | | |
| { | | { | |
|
| access::rw(m).at(lrow, lcol) += val; | | for(uword row = start_row; row < end_row; ++row) | |
| | | { | |
| | | access::rw(m).at(row, col) += val; | |
| | | } | |
| } | | } | |
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | const uword new_n_nonzero = m.n_nonzero; | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 128 | | skipping to change at line 129 | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator-=(const eT val) | | SpSubview<eT>::operator-=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(val == eT(0)) | | if(val == eT(0)) | |
| { | | { | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| const uword lstart_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword lend_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | const uword start_col = aux_col1; | |
| const uword lstart_col = aux_col1; | | const uword end_col = aux_col1 + n_cols; | |
| const uword lend_col = aux_col1 + n_cols; | | | |
| | | | |
| const uword old_n_nonzero = m.n_nonzero; | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
|
| for(uword lcol = lstart_col; lcol < lend_col; ++lcol) | | for(uword col = start_col; col < end_col; ++col) | |
| for(uword lrow = lstart_row; lrow < lend_row; ++lrow) | | | |
| { | | { | |
|
| access::rw(m).at(lrow, lcol) -= val; | | for(uword row = start_row; row < end_row; ++row) | |
| | | { | |
| | | access::rw(m).at(row, col) -= val; | |
| | | } | |
| } | | } | |
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | const uword new_n_nonzero = m.n_nonzero; | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 168 | | skipping to change at line 170 | |
| // Turn it all into zeros. | | // Turn it all into zeros. | |
| for(iterator it(*this); it != end(); ++it) | | for(iterator it(*this); it != end(); ++it) | |
| { | | { | |
| (*it) = eT(0); // zero out the value. | | (*it) = eT(0); // zero out the value. | |
| it.internal_pos--; | | it.internal_pos--; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| const uword lstart_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword lend_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | const uword start_col = aux_col1; | |
| const uword lstart_col = aux_col1; | | const uword end_col = aux_col1 + n_cols; | |
| const uword lend_col = aux_col1 + n_cols; | | | |
| | | | |
|
| for(uword c = lstart_col; c < lend_col; ++c) | | for(uword c = start_col; c < end_col; ++c) | |
| { | | { | |
| for(uword r = m.col_ptrs[c]; r < m.col_ptrs[c + 1]; ++r) | | for(uword r = m.col_ptrs[c]; r < m.col_ptrs[c + 1]; ++r) | |
| { | | { | |
|
| if(m.row_indices[r] >= lstart_row && m.row_indices[r] < lend_row) | | if(m.row_indices[r] >= start_row && m.row_indices[r] < end_row) | |
| { | | { | |
| access::rw(m.values[r]) *= val; | | access::rw(m.values[r]) *= val; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator/=(const eT val) | | SpSubview<eT>::operator/=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const uword lstart_col = aux_col1; | | const uword start_col = aux_col1; | |
| const uword lend_col = aux_col1 + n_cols; | | const uword end_col = aux_col1 + n_cols; | |
| | | const uword start_row = aux_row1; | |
| const uword lstart_row = aux_row1; | | const uword end_row = aux_row1 + n_rows; | |
| const uword lend_row = aux_row1 + n_rows; | | | |
| | | | |
| const uword old_n_nonzero = m.n_nonzero; | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
|
| for(uword c = lstart_col; c < lend_col; ++c) | | for(uword c = start_col; c < end_col; ++c) | |
| for(uword r = lstart_row; r < lend_row; ++r) | | | |
| { | | { | |
|
| access::rw(m).at(r, c) /= val; | | for(uword r = start_row; r < end_row; ++r) | |
| | | { | |
| | | access::rw(m).at(r, c) /= val; | |
| | | } | |
| } | | } | |
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | const uword new_n_nonzero = m.n_nonzero; | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 640 | | skipping to change at line 642 | |
| SpSubview<eT>::operator/=(const SpBase<eT, T1>& x) | | SpSubview<eT>::operator/=(const SpBase<eT, T1>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| SpProxy<T1> p(x.get_ref()); | | SpProxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise division"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise division"); | |
| | | | |
| if(p.is_alias(m) == false) | | if(p.is_alias(m) == false) | |
| { | | { | |
|
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | for(uword col = 0; col < n_cols; ++col) | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
|
| at(lrow,lcol) /= p.at(lrow,lcol); | | at(row,col) /= p.at(row,col); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| const SpMat<eT> tmp(p.Q); | | const SpMat<eT> tmp(p.Q); | |
| | | | |
| (*this).operator/=(tmp); | | (*this).operator/=(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| | | | |
| skipping to change at line 667 | | skipping to change at line 669 | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::fill(const eT val) | | SpSubview<eT>::fill(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(val != eT(0)) | | if(val != eT(0)) | |
| { | | { | |
| // TODO: implement a faster version; the code below is slow | | // TODO: implement a faster version; the code below is slow | |
| | | | |
|
| const uword lstart_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword lend_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | const uword start_col = aux_col1; | |
| const uword lstart_col = aux_col1; | | const uword end_col = aux_col1 + n_cols; | |
| const uword lend_col = aux_col1 + n_cols; | | | |
| | | | |
| const uword orig_nonzero = m.n_nonzero; | | const uword orig_nonzero = m.n_nonzero; | |
| | | | |
| // iterate over our part of the sparse matrix | | // iterate over our part of the sparse matrix | |
|
| for(uword lcol = lstart_col; lcol < lend_col; ++lcol) | | for(uword col = start_col; col < end_col; ++col) | |
| for(uword lrow = lstart_row; lrow < lend_row; ++lrow) | | for(uword row = start_row; row < end_row; ++row) | |
| { | | { | |
|
| access::rw(m).at(lrow, lcol) = val; | | access::rw(m).at(row, col) = val; | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero); | | access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero); | |
| | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| (*this).zeros(); | | (*this).zeros(); | |
| } | | } | |
| } | | } | |
| | | | |
| skipping to change at line 748 | | skipping to change at line 749 | |
| | | | |
| access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero); | | access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| SpValProxy<SpSubview<eT> > | | SpValProxy<SpSubview<eT> > | |
| SpSubview<eT>::operator[](const uword i) | | SpSubview<eT>::operator[](const uword i) | |
| { | | { | |
|
| const uword lrow = i % n_rows; | | const uword row = i % n_rows; | |
| const uword lcol = i / n_rows; | | const uword col = i / n_rows; | |
| | | | |
|
| return (*this).at(lrow, lcol); | | return (*this).at(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| eT | | eT | |
| SpSubview<eT>::operator[](const uword i) const | | SpSubview<eT>::operator[](const uword i) const | |
| { | | { | |
|
| const uword lrow = i % n_rows; | | const uword row = i % n_rows; | |
| const uword lcol = i / n_rows; | | const uword col = i / n_rows; | |
| | | | |
|
| return (*this).at(lrow, lcol); | | return (*this).at(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| SpValProxy< SpSubview<eT> > | | SpValProxy< SpSubview<eT> > | |
| SpSubview<eT>::operator()(const uword i) | | SpSubview<eT>::operator()(const uword i) | |
| { | | { | |
| arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bou
nds"); | | arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bou
nds"); | |
| | | | |
|
| const uword lrow = i % n_rows; | | const uword row = i % n_rows; | |
| const uword lcol = i / n_rows; | | const uword col = i / n_rows; | |
| | | | |
|
| return (*this).at(lrow, lcol); | | return (*this).at(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| eT | | eT | |
| SpSubview<eT>::operator()(const uword i) const | | SpSubview<eT>::operator()(const uword i) const | |
| { | | { | |
| arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bou
nds"); | | arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bou
nds"); | |
| | | | |
|
| const uword lrow = i % n_rows; | | const uword row = i % n_rows; | |
| const uword lcol = i / n_rows; | | const uword col = i / n_rows; | |
| | | | |
|
| return (*this).at(lrow, lcol); | | return (*this).at(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| SpValProxy< SpSubview<eT> > | | SpValProxy< SpSubview<eT> > | |
| SpSubview<eT>::operator()(const uword in_row, const uword in_col) | | SpSubview<eT>::operator()(const uword in_row, const uword in_col) | |
| { | | { | |
| arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::o
perator(): index out of bounds"); | | arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::o
perator(): index out of bounds"); | |
| | | | |
| | | | |
| skipping to change at line 822 | | skipping to change at line 823 | |
| | | | |
| return (*this).at(in_row, in_col); | | return (*this).at(in_row, in_col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| SpValProxy< SpSubview<eT> > | | SpValProxy< SpSubview<eT> > | |
| SpSubview<eT>::at(const uword i) | | SpSubview<eT>::at(const uword i) | |
| { | | { | |
|
| const uword lrow = i % n_rows; | | const uword row = i % n_rows; | |
| const uword lcol = i / n_cols; | | const uword col = i / n_cols; | |
| | | | |
|
| return (*this).at(lrow, lcol); | | return (*this).at(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| eT | | eT | |
| SpSubview<eT>::at(const uword i) const | | SpSubview<eT>::at(const uword i) const | |
| { | | { | |
|
| const uword lrow = i % n_rows; | | const uword row = i % n_rows; | |
| const uword lcol = i / n_cols; | | const uword col = i / n_cols; | |
| | | | |
|
| return (*this).at(lrow, lcol); | | return (*this).at(row, col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| SpValProxy< SpSubview<eT> > | | SpValProxy< SpSubview<eT> > | |
| SpSubview<eT>::at(const uword in_row, const uword in_col) | | SpSubview<eT>::at(const uword in_row, const uword in_col) | |
| { | | { | |
| const uword colptr = m.col_ptrs[in_col + aux_col1]; | | const uword colptr = m.col_ptrs[in_col + aux_col1]; | |
| const uword next_colptr = m.col_ptrs[in_col + aux_col1 + 1]; | | const uword next_colptr = m.col_ptrs[in_col + aux_col1 + 1]; | |
| | | | |
| skipping to change at line 1192 | | skipping to change at line 1193 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::swap_rows(const uword in_row1, const uword in_row2) | | SpSubview<eT>::swap_rows(const uword in_row1, const uword in_row2) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::
swap_rows(): invalid row index"); | | arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::
swap_rows(): invalid row index"); | |
| | | | |
|
| const uword lstart_col = aux_col1; | | const uword start_col = aux_col1; | |
| const uword lend_col = aux_col1 + n_cols; | | const uword end_col = aux_col1 + n_cols; | |
| | | | |
|
| for(uword c = lstart_col; c < lend_col; ++c) | | for(uword c = start_col; c < end_col; ++c) | |
| { | | { | |
| eT val = m.at(in_row1 + aux_row1, c); | | eT val = m.at(in_row1 + aux_row1, c); | |
| access::rw(m).at(in_row2 + aux_row1, c) = m.at(in_row1 + aux_row1, c); | | access::rw(m).at(in_row2 + aux_row1, c) = m.at(in_row1 + aux_row1, c); | |
| access::rw(m).at(in_row1 + aux_row1, c) = val; | | access::rw(m).at(in_row1 + aux_row1, c) = val; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::swap_cols(const uword in_col1, const uword in_col2) | | SpSubview<eT>::swap_cols(const uword in_col1, const uword in_col2) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::
swap_cols(): invalid column index"); | | arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::
swap_cols(): invalid column index"); | |
| | | | |
|
| const uword lstart_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword lend_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | | |
|
| for(uword r = lstart_row; r < lend_row; ++r) | | for(uword r = start_row; r < end_row; ++r) | |
| { | | { | |
| eT val = m.at(r, in_col1 + aux_col1); | | eT val = m.at(r, in_col1 + aux_col1); | |
| access::rw(m).at(r, in_col1 + aux_col1) = m.at(r, in_col2 + aux_col1); | | access::rw(m).at(r, in_col1 + aux_col1) = m.at(r, in_col2 + aux_col1); | |
| access::rw(m).at(r, in_col2 + aux_col1) = val; | | access::rw(m).at(r, in_col2 + aux_col1) = val; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::iterator | | typename SpSubview<eT>::iterator | |
| | | | |
End of changes. 39 change blocks. |
| 75 lines changed or deleted | | 76 lines changed or added | |
|
| op_cx_scalar_meat.hpp | | op_cx_scalar_meat.hpp | |
|
| // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2010 NICTA (www.nicta.com.au) | |
| // Copyright (C) 2008-2013 Conrad Sanderson | | // Copyright (C) 2008-2010 Conrad Sanderson | |
| // | | // | |
| // This file is part of the Armadillo C++ library. | | // This file is part of the Armadillo C++ library. | |
| // It is provided without any warranty of fitness | | // It is provided without any warranty of fitness | |
| // for any purpose. You can redistribute this file | | // for any purpose. You can redistribute this file | |
| // and/or modify it under the terms of the GNU | | // and/or modify it under the terms of the GNU | |
| // Lesser General Public License (LGPL) as published | | // Lesser General Public License (LGPL) as published | |
| // by the Free Software Foundation, either version 3 | | // by the Free Software Foundation, either version 3 | |
| // of the License or (at your option) any later version. | | // of the License or (at your option) any later version. | |
| // (see http://www.opensource.org/licenses for more info) | | // (see http://www.opensource.org/licenses for more info) | |
| | | | |
| | | | |
| skipping to change at line 28 | | skipping to change at line 28 | |
| void | | void | |
| op_cx_scalar_times::apply | | op_cx_scalar_times::apply | |
| ( | | ( | |
| Mat< typename std::complex<typename T1::pod_type> >& out, | | Mat< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_times>& X | | const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_times>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| const uword n_rows = A.get_n_rows(); | | out.set_size(A.get_n_rows(), A.get_n_cols()); | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| out.set_size(n_rows, n_cols); | | | |
| | | | |
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
|
| | | const uword n_elem = out.n_elem; | |
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| const uword n_elem = A.get_n_elem(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| out_mem[i] = A[i] * k; | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword col=0; col < n_cols; ++col) | | out_mem[i] = A[i] * k; | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | | |
| *out_mem = A.at(row,col) * k; ++out_mem; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_plus::apply | | op_cx_scalar_plus::apply | |
| ( | | ( | |
| Mat< typename std::complex<typename T1::pod_type> >& out, | | Mat< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_plus>& X | | const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_plus>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| const uword n_rows = A.get_n_rows(); | | out.set_size(A.get_n_rows(), A.get_n_cols()); | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| out.set_size(n_rows, n_cols); | | | |
| | | | |
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
|
| | | const uword n_elem = out.n_elem; | |
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| const uword n_elem = A.get_n_elem(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| out_mem[i] = A[i] + k; | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword col=0; col < n_cols; ++col) | | out_mem[i] = A[i] + k; | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | | |
| *out_mem = A.at(row,col) + k; ++out_mem; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_minus_pre::apply | | op_cx_scalar_minus_pre::apply | |
| ( | | ( | |
| Mat< typename std::complex<typename T1::pod_type> >& out, | | Mat< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_minus_pre>& X | | const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_minus_pre>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| const uword n_rows = A.get_n_rows(); | | out.set_size(A.get_n_rows(), A.get_n_cols()); | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| out.set_size(n_rows, n_cols); | | | |
| | | | |
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
|
| | | const uword n_elem = out.n_elem; | |
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| const uword n_elem = A.get_n_elem(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| out_mem[i] = k - A[i]; | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword col=0; col < n_cols; ++col) | | out_mem[i] = k - A[i]; | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | | |
| *out_mem = k - A.at(row,col); ++out_mem; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_minus_post::apply | | op_cx_scalar_minus_post::apply | |
| ( | | ( | |
| Mat< typename std::complex<typename T1::pod_type> >& out, | | Mat< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_minus_post>& X | | const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_minus_post>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| const uword n_rows = A.get_n_rows(); | | out.set_size(A.get_n_rows(), A.get_n_cols()); | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| out.set_size(n_rows, n_cols); | | | |
| | | | |
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
|
| | | const uword n_elem = out.n_elem; | |
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| const uword n_elem = A.get_n_elem(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| out_mem[i] = A[i] - k; | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword col=0; col < n_cols; ++col) | | out_mem[i] = A[i] - k; | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | | |
| *out_mem = A.at(row,col) - k; ++out_mem; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_div_pre::apply | | op_cx_scalar_div_pre::apply | |
| ( | | ( | |
| Mat< typename std::complex<typename T1::pod_type> >& out, | | Mat< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_div_pre>& X | | const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_div_pre>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| const uword n_rows = A.get_n_rows(); | | out.set_size(A.get_n_rows(), A.get_n_cols()); | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| out.set_size(n_rows, n_cols); | | | |
| | | | |
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
|
| | | const uword n_elem = out.n_elem; | |
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| const uword n_elem = A.get_n_elem(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| out_mem[i] = k / A[i]; | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword col=0; col < n_cols; ++col) | | out_mem[i] = k / A[i]; | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | | |
| *out_mem = k / A.at(row,col); ++out_mem; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_div_post::apply | | op_cx_scalar_div_post::apply | |
| ( | | ( | |
| Mat< typename std::complex<typename T1::pod_type> >& out, | | Mat< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_div_post>& X | | const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar
_div_post>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| const uword n_rows = A.get_n_rows(); | | out.set_size(A.get_n_rows(), A.get_n_cols()); | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| out.set_size(n_rows, n_cols); | | | |
| | | | |
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
|
| | | const uword n_elem = out.n_elem; | |
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| const uword n_elem = A.get_n_elem(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| out_mem[i] = A[i] / k; | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword col=0; col < n_cols; ++col) | | out_mem[i] = A[i] / k; | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | | |
| *out_mem = A.at(row,col) / k; ++out_mem; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| | | | |
| // | | // | |
| // | | // | |
| // | | // | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_times::apply | | op_cx_scalar_times::apply | |
| ( | | ( | |
| Cube< typename std::complex<typename T1::pod_type> >& out, | | Cube< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_times>& X | | const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_times>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const ProxyCube<T1> A(X.m); | | const ProxyCube<T1> A(X.m); | |
| | | | |
| out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | | out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | |
| | | | |
|
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
| const uword n_elem = out.n_elem; | | const uword n_elem = out.n_elem; | |
|
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
|
| // TODO: implement handling for ProxyCube<T1>::prefer_at_accessor == true | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| out_mem[i] = A[i] * k; | | out_mem[i] = A[i] * k; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_plus::apply | | op_cx_scalar_plus::apply | |
| ( | | ( | |
| Cube< typename std::complex<typename T1::pod_type> >& out, | | Cube< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_plus>& X | | const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_plus>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const ProxyCube<T1> A(X.m); | | const ProxyCube<T1> A(X.m); | |
| | | | |
| out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | | out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | |
| | | | |
|
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
| const uword n_elem = out.n_elem; | | const uword n_elem = out.n_elem; | |
|
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| out_mem[i] = A[i] + k; | | out_mem[i] = A[i] + k; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_minus_pre::apply | | op_cx_scalar_minus_pre::apply | |
| ( | | ( | |
| Cube< typename std::complex<typename T1::pod_type> >& out, | | Cube< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_minus_pre>& X | | const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_minus_pre>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const ProxyCube<T1> A(X.m); | | const ProxyCube<T1> A(X.m); | |
| | | | |
| out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | | out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | |
| | | | |
|
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
| const uword n_elem = out.n_elem; | | const uword n_elem = out.n_elem; | |
|
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| out_mem[i] = k - A[i]; | | out_mem[i] = k - A[i]; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_minus_post::apply | | op_cx_scalar_minus_post::apply | |
| ( | | ( | |
| Cube< typename std::complex<typename T1::pod_type> >& out, | | Cube< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_minus_post>& X | | const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_minus_post>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const ProxyCube<T1> A(X.m); | | const ProxyCube<T1> A(X.m); | |
| | | | |
| out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | | out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | |
| | | | |
|
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
| const uword n_elem = out.n_elem; | | const uword n_elem = out.n_elem; | |
|
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| out_mem[i] = A[i] - k; | | out_mem[i] = A[i] - k; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_div_pre::apply | | op_cx_scalar_div_pre::apply | |
| ( | | ( | |
| Cube< typename std::complex<typename T1::pod_type> >& out, | | Cube< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_div_pre>& X | | const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_div_pre>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const ProxyCube<T1> A(X.m); | | const ProxyCube<T1> A(X.m); | |
| | | | |
| out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | | out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | |
| | | | |
|
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
| const uword n_elem = out.n_elem; | | const uword n_elem = out.n_elem; | |
|
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| out_mem[i] = k / A[i]; | | out_mem[i] = k / A[i]; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_cx_scalar_div_post::apply | | op_cx_scalar_div_post::apply | |
| ( | | ( | |
| Cube< typename std::complex<typename T1::pod_type> >& out, | | Cube< typename std::complex<typename T1::pod_type> >& out, | |
| const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_div_post>& X | | const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_sc
alar_div_post>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename std::complex<typename T1::pod_type> eT; | | typedef typename std::complex<typename T1::pod_type> eT; | |
|
| | | typedef typename T1::pod_type T; | |
| | | | |
| const ProxyCube<T1> A(X.m); | | const ProxyCube<T1> A(X.m); | |
| | | | |
| out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | | out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices()); | |
| | | | |
|
| const eT k = X.aux_out_eT; | | const eT k = X.aux_out_eT; | |
| const uword n_elem = out.n_elem; | | const uword n_elem = out.n_elem; | |
|
| eT* out_mem = out.memptr(); | | eT* out_mem = out.memptr(); | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| out_mem[i] = A[i] / k; | | out_mem[i] = A[i] / k; | |
| } | | } | |
| } | | } | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 50 change blocks. |
| 129 lines changed or deleted | | 50 lines changed or added | |
|
| op_find_meat.hpp | | op_find_meat.hpp | |
|
| // Copyright (C) 2010-2013 NICTA (www.nicta.com.au) | | // Copyright (C) 2010 NICTA (www.nicta.com.au) | |
| // Copyright (C) 2010-2013 Conrad Sanderson | | // Copyright (C) 2010 Conrad Sanderson | |
| // Copyright (C) 2010 Dimitrios Bouzas | | // Copyright (C) 2010 Dimitrios Bouzas | |
| // | | // | |
| // This file is part of the Armadillo C++ library. | | // This file is part of the Armadillo C++ library. | |
| // It is provided without any warranty of fitness | | // It is provided without any warranty of fitness | |
| // for any purpose. You can redistribute this file | | // for any purpose. You can redistribute this file | |
| // and/or modify it under the terms of the GNU | | // and/or modify it under the terms of the GNU | |
| // Lesser General Public License (LGPL) as published | | // Lesser General Public License (LGPL) as published | |
| // by the Free Software Foundation, either version 3 | | // by the Free Software Foundation, either version 3 | |
| // of the License or (at your option) any later version. | | // of the License or (at your option) any later version. | |
| // (see http://www.opensource.org/licenses for more info) | | // (see http://www.opensource.org/licenses for more info) | |
| | | | |
| skipping to change at line 28 | | skipping to change at line 28 | |
| inline | | inline | |
| uword | | uword | |
| op_find::helper | | op_find::helper | |
| ( | | ( | |
| Mat<uword>& indices, | | Mat<uword>& indices, | |
| const Base<typename T1::elem_type, T1>& X | | const Base<typename T1::elem_type, T1>& X | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | typedef typename Proxy<T1>::ea_type ea_type; | |
| | | | |
| const Proxy<T1> A(X.get_ref()); | | const Proxy<T1> A(X.get_ref()); | |
| | | | |
|
| | | ea_type PA = A.get_ea(); | |
| const uword n_elem = A.get_n_elem(); | | const uword n_elem = A.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | | |
| typename Proxy<T1>::ea_type PA = A.get_ea(); | | | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | | |
| { | | | |
| if(PA[i] != eT(0)) { indices_mem[n_nz] = i; ++n_nz; } | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| const uword n_rows = A.get_n_rows(); | | if(PA[i] != eT(0)) | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
| uword i = 0; | | | |
| | | | |
| for(uword col=0; col < n_cols; ++col) | | | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | { | |
|
| if(A.at(row,col) != eT(0)) { indices_mem[n_nz] = i; ++n_nz; } | | indices_mem[n_nz] = i; | |
| | | ++n_nz; | |
| ++i; | | | |
| } | | } | |
| } | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1, typename op_type> | | template<typename T1, typename op_type> | |
| inline | | inline | |
| uword | | uword | |
| op_find::helper | | op_find::helper | |
| | | | |
| skipping to change at line 82 | | skipping to change at line 68 | |
| Mat<uword>& indices, | | Mat<uword>& indices, | |
| const mtOp<uword, T1, op_type>& X, | | const mtOp<uword, T1, op_type>& X, | |
| const typename arma_op_rel_only<op_type>::result junk1, | | const typename arma_op_rel_only<op_type>::result junk1, | |
| const typename arma_not_cx<typename T1::elem_type>::result junk2 | | const typename arma_not_cx<typename T1::elem_type>::result junk2 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk1); | | arma_ignore(junk1); | |
| arma_ignore(junk2); | | arma_ignore(junk2); | |
| | | | |
|
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | typedef typename Proxy<T1>::ea_type ea_type; | |
| | | | |
| const eT val = X.aux; | | const eT val = X.aux; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| | | ea_type PA = A.get_ea(); | |
| const uword n_elem = A.get_n_elem(); | | const uword n_elem = A.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
|
| if(Proxy<T1>::prefer_at_accessor == false) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
|
| typename Proxy<T1>::ea_type PA = A.get_ea(); | | const eT tmp = PA[i]; | |
| | | | |
| uword i,j; | | | |
| for(i=0, j=1; j < n_elem; i+=2, j+=2) | | | |
| { | | | |
| const eT tpi = PA[i]; | | | |
| const eT tpj = PA[j]; | | | |
| | | | |
| bool not_zero_i; | | | |
| bool not_zero_j; | | | |
| | | | |
| if(is_same_type<op_type, op_rel_lt_pre >::value == true) { no | | | |
| t_zero_i = (val < tpi); } | | | |
| else if(is_same_type<op_type, op_rel_lt_post >::value == true) { no | | | |
| t_zero_i = (tpi < val); } | | | |
| else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { no | | | |
| t_zero_i = (val > tpi); } | | | |
| else if(is_same_type<op_type, op_rel_gt_post >::value == true) { no | | | |
| t_zero_i = (tpi > val); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { no | | | |
| t_zero_i = (val <= tpi); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { no | | | |
| t_zero_i = (tpi <= val); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { no | | | |
| t_zero_i = (val >= tpi); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { no | | | |
| t_zero_i = (tpi >= val); } | | | |
| else if(is_same_type<op_type, op_rel_eq >::value == true) { no | | | |
| t_zero_i = (tpi == val); } | | | |
| else if(is_same_type<op_type, op_rel_noteq >::value == true) { no | | | |
| t_zero_i = (tpi != val); } | | | |
| else not_zero_i = false; | | | |
| | | | |
| if(is_same_type<op_type, op_rel_lt_pre >::value == true) { no | | | |
| t_zero_j = (val < tpj); } | | | |
| else if(is_same_type<op_type, op_rel_lt_post >::value == true) { no | | | |
| t_zero_j = (tpj < val); } | | | |
| else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { no | | | |
| t_zero_j = (val > tpj); } | | | |
| else if(is_same_type<op_type, op_rel_gt_post >::value == true) { no | | | |
| t_zero_j = (tpj > val); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { no | | | |
| t_zero_j = (val <= tpj); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { no | | | |
| t_zero_j = (tpj <= val); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { no | | | |
| t_zero_j = (val >= tpj); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { no | | | |
| t_zero_j = (tpj >= val); } | | | |
| else if(is_same_type<op_type, op_rel_eq >::value == true) { no | | | |
| t_zero_j = (tpj == val); } | | | |
| else if(is_same_type<op_type, op_rel_noteq >::value == true) { no | | | |
| t_zero_j = (tpj != val); } | | | |
| else not_zero_j = false; | | | |
| | | | |
| if(not_zero_i == true) { indices_mem[n_nz] = i; ++n_nz; } | | | |
| if(not_zero_j == true) { indices_mem[n_nz] = j; ++n_nz; } | | | |
| } | | | |
| | | | |
| if(i < n_elem) | | | |
| { | | | |
| bool not_zero; | | | |
| | | | |
| const eT tmp = PA[i]; | | | |
| | | | |
| if(is_same_type<op_type, op_rel_lt_pre >::value == true) { no | | | |
| t_zero = (val < tmp); } | | | |
| else if(is_same_type<op_type, op_rel_lt_post >::value == true) { no | | | |
| t_zero = (tmp < val); } | | | |
| else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { no | | | |
| t_zero = (val > tmp); } | | | |
| else if(is_same_type<op_type, op_rel_gt_post >::value == true) { no | | | |
| t_zero = (tmp > val); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { no | | | |
| t_zero = (val <= tmp); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { no | | | |
| t_zero = (tmp <= val); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { no | | | |
| t_zero = (val >= tmp); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { no | | | |
| t_zero = (tmp >= val); } | | | |
| else if(is_same_type<op_type, op_rel_eq >::value == true) { no | | | |
| t_zero = (tmp == val); } | | | |
| else if(is_same_type<op_type, op_rel_noteq >::value == true) { no | | | |
| t_zero = (tmp != val); } | | | |
| else not_zero = false; | | | |
| | | | |
|
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | bool not_zero; | |
| } | | | |
| } | | | |
| else | | | |
| { | | | |
| const uword n_rows = A.get_n_rows(); | | | |
| const uword n_cols = A.get_n_cols(); | | | |
| | | | |
|
| uword i = 0; | | if(is_same_type<op_type, op_rel_lt_pre >::value == true) { not_ | |
| | | zero = (val < tmp); } | |
| | | else if(is_same_type<op_type, op_rel_lt_post >::value == true) { not_ | |
| | | zero = (tmp < val); } | |
| | | else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { not_ | |
| | | zero = (val > tmp); } | |
| | | else if(is_same_type<op_type, op_rel_gt_post >::value == true) { not_ | |
| | | zero = (tmp > val); } | |
| | | else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { not_ | |
| | | zero = (val <= tmp); } | |
| | | else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { not_ | |
| | | zero = (tmp <= val); } | |
| | | else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { not_ | |
| | | zero = (val >= tmp); } | |
| | | else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { not_ | |
| | | zero = (tmp >= val); } | |
| | | else if(is_same_type<op_type, op_rel_eq >::value == true) { not_ | |
| | | zero = (tmp == val); } | |
| | | else if(is_same_type<op_type, op_rel_noteq >::value == true) { not_ | |
| | | zero = (tmp != val); } | |
| | | else not_zero = false; | |
| | | | |
|
| for(uword col=0; col < n_cols; ++col) | | if(not_zero == true) | |
| for(uword row=0; row < n_rows; ++row) | | | |
| { | | { | |
|
| const eT tmp = A.at(row,col); | | indices_mem[n_nz] = i; | |
| | | ++n_nz; | |
| bool not_zero; | | | |
| | | | |
| if(is_same_type<op_type, op_rel_lt_pre >::value == true) { no | | | |
| t_zero = (val < tmp); } | | | |
| else if(is_same_type<op_type, op_rel_lt_post >::value == true) { no | | | |
| t_zero = (tmp < val); } | | | |
| else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { no | | | |
| t_zero = (val > tmp); } | | | |
| else if(is_same_type<op_type, op_rel_gt_post >::value == true) { no | | | |
| t_zero = (tmp > val); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { no | | | |
| t_zero = (val <= tmp); } | | | |
| else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { no | | | |
| t_zero = (tmp <= val); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { no | | | |
| t_zero = (val >= tmp); } | | | |
| else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { no | | | |
| t_zero = (tmp >= val); } | | | |
| else if(is_same_type<op_type, op_rel_eq >::value == true) { no | | | |
| t_zero = (tmp == val); } | | | |
| else if(is_same_type<op_type, op_rel_noteq >::value == true) { no | | | |
| t_zero = (tmp != val); } | | | |
| else not_zero = false; | | | |
| | | | |
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | | |
| | | | |
| ++i; | | | |
| } | | } | |
| } | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1, typename op_type> | | template<typename T1, typename op_type> | |
| inline | | inline | |
| uword | | uword | |
| op_find::helper | | op_find::helper | |
| | | | |
| skipping to change at line 214 | | skipping to change at line 133 | |
| arma_ignore(junk1); | | arma_ignore(junk1); | |
| arma_ignore(junk2); | | arma_ignore(junk2); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| typedef typename Proxy<T1>::ea_type ea_type; | | typedef typename Proxy<T1>::ea_type ea_type; | |
| | | | |
| const eT val = X.aux; | | const eT val = X.aux; | |
| | | | |
| const Proxy<T1> A(X.m); | | const Proxy<T1> A(X.m); | |
| | | | |
|
| ea_type PA = A.get_ea(); | | ea_type PA = A.get_ea(); | |
| const uword n_elem = A.get_n_elem(); | | const uword n_elem = A.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| const eT tmp = PA[i]; | | const eT tmp = PA[i]; | |
| | | | |
| bool not_zero; | | bool not_zero; | |
| | | | |
| if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero
= (tmp == val); } | | if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero
= (tmp == val); } | |
| else if(is_same_type<op_type, op_rel_noteq>::value == true) { not_zero
= (tmp != val); } | | else if(is_same_type<op_type, op_rel_noteq>::value == true) { not_zero
= (tmp != val); } | |
| else not_zero = false; | | else not_zero = false; | |
| | | | |
|
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | if(not_zero == true) | |
| | | { | |
| | | indices_mem[n_nz] = i; | |
| | | ++n_nz; | |
| | | } | |
| } | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1, typename T2, typename glue_type> | | template<typename T1, typename T2, typename glue_type> | |
| inline | | inline | |
| uword | | uword | |
| op_find::helper | | op_find::helper | |
| ( | | ( | |
| | | | |
| skipping to change at line 266 | | skipping to change at line 189 | |
| typedef typename T2::elem_type eT2; | | typedef typename T2::elem_type eT2; | |
| | | | |
| typedef typename Proxy<T1>::ea_type ea_type1; | | typedef typename Proxy<T1>::ea_type ea_type1; | |
| typedef typename Proxy<T2>::ea_type ea_type2; | | typedef typename Proxy<T2>::ea_type ea_type2; | |
| | | | |
| const Proxy<T1> A(X.A); | | const Proxy<T1> A(X.A); | |
| const Proxy<T2> B(X.B); | | const Proxy<T2> B(X.B); | |
| | | | |
| arma_debug_assert_same_size(A, B, "relational operator"); | | arma_debug_assert_same_size(A, B, "relational operator"); | |
| | | | |
|
| ea_type1 PA = A.get_ea(); | | ea_type1 PA = A.get_ea(); | |
| ea_type2 PB = B.get_ea(); | | ea_type2 PB = B.get_ea(); | |
| | | | |
| const uword n_elem = B.get_n_elem(); | | const uword n_elem = B.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| const eT1 tmp1 = PA[i]; | | const eT1 tmp1 = PA[i]; | |
| | | | |
| skipping to change at line 291 | | skipping to change at line 213 | |
| bool not_zero; | | bool not_zero; | |
| | | | |
| if(is_same_type<glue_type, glue_rel_lt >::value == true) { not
_zero = (tmp1 < tmp2); } | | if(is_same_type<glue_type, glue_rel_lt >::value == true) { not
_zero = (tmp1 < tmp2); } | |
| else if(is_same_type<glue_type, glue_rel_gt >::value == true) { not
_zero = (tmp1 > tmp2); } | | else if(is_same_type<glue_type, glue_rel_gt >::value == true) { not
_zero = (tmp1 > tmp2); } | |
| else if(is_same_type<glue_type, glue_rel_lteq >::value == true) { not
_zero = (tmp1 <= tmp2); } | | else if(is_same_type<glue_type, glue_rel_lteq >::value == true) { not
_zero = (tmp1 <= tmp2); } | |
| else if(is_same_type<glue_type, glue_rel_gteq >::value == true) { not
_zero = (tmp1 >= tmp2); } | | else if(is_same_type<glue_type, glue_rel_gteq >::value == true) { not
_zero = (tmp1 >= tmp2); } | |
| else if(is_same_type<glue_type, glue_rel_eq >::value == true) { not
_zero = (tmp1 == tmp2); } | | else if(is_same_type<glue_type, glue_rel_eq >::value == true) { not
_zero = (tmp1 == tmp2); } | |
| else if(is_same_type<glue_type, glue_rel_noteq >::value == true) { not
_zero = (tmp1 != tmp2); } | | else if(is_same_type<glue_type, glue_rel_noteq >::value == true) { not
_zero = (tmp1 != tmp2); } | |
| else not_zero = false; | | else not_zero = false; | |
| | | | |
|
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | if(not_zero == true) | |
| | | { | |
| | | indices_mem[n_nz] = i; | |
| | | ++n_nz; | |
| | | } | |
| } | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1, typename T2, typename glue_type> | | template<typename T1, typename T2, typename glue_type> | |
| inline | | inline | |
| uword | | uword | |
| op_find::helper | | op_find::helper | |
| ( | | ( | |
| | | | |
| skipping to change at line 322 | | skipping to change at line 248 | |
| arma_ignore(junk3); | | arma_ignore(junk3); | |
| | | | |
| typedef typename Proxy<T1>::ea_type ea_type1; | | typedef typename Proxy<T1>::ea_type ea_type1; | |
| typedef typename Proxy<T2>::ea_type ea_type2; | | typedef typename Proxy<T2>::ea_type ea_type2; | |
| | | | |
| const Proxy<T1> A(X.A); | | const Proxy<T1> A(X.A); | |
| const Proxy<T2> B(X.B); | | const Proxy<T2> B(X.B); | |
| | | | |
| arma_debug_assert_same_size(A, B, "relational operator"); | | arma_debug_assert_same_size(A, B, "relational operator"); | |
| | | | |
|
| ea_type1 PA = A.get_ea(); | | ea_type1 PA = A.get_ea(); | |
| ea_type2 PB = B.get_ea(); | | ea_type2 PB = B.get_ea(); | |
| | | | |
| const uword n_elem = B.get_n_elem(); | | const uword n_elem = B.get_n_elem(); | |
| | | | |
| indices.set_size(n_elem, 1); | | indices.set_size(n_elem, 1); | |
| | | | |
| uword* indices_mem = indices.memptr(); | | uword* indices_mem = indices.memptr(); | |
| uword n_nz = 0; | | uword n_nz = 0; | |
| | | | |
| for(uword i=0; i<n_elem; ++i) | | for(uword i=0; i<n_elem; ++i) | |
| { | | { | |
| bool not_zero; | | bool not_zero; | |
| | | | |
| if(is_same_type<glue_type, glue_rel_eq >::value == true) { not
_zero = (PA[i] == PB[i]); } | | if(is_same_type<glue_type, glue_rel_eq >::value == true) { not
_zero = (PA[i] == PB[i]); } | |
| else if(is_same_type<glue_type, glue_rel_noteq >::value == true) { not
_zero = (PA[i] != PB[i]); } | | else if(is_same_type<glue_type, glue_rel_noteq >::value == true) { not
_zero = (PA[i] != PB[i]); } | |
| else not_zero = false; | | else not_zero = false; | |
| | | | |
|
| if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } | | if(not_zero == true) | |
| | | { | |
| | | indices_mem[n_nz] = i; | |
| | | ++n_nz; | |
| | | } | |
| } | | } | |
| | | | |
| return n_nz; | | return n_nz; | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X) | | op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X) | |
| { | | { | |
| | | | |
End of changes. 20 change blocks. |
| 160 lines changed or deleted | | 59 lines changed or added | |
|
| unwrap.hpp | | unwrap.hpp | |
| | | | |
| skipping to change at line 1167 | | skipping to change at line 1167 | |
| | | | |
| inline eT get_val() const { return val; } | | inline eT get_val() const { return val; } | |
| | | | |
| static const bool do_trans = false; | | static const bool do_trans = false; | |
| static const bool do_times = true; | | static const bool do_times = true; | |
| | | | |
| const eT val; | | const eT val; | |
| const Mat<eT>& M; | | const Mat<eT>& M; | |
| }; | | }; | |
| | | | |
|
| template<typename T1> | | | |
| struct partial_unwrap_neg_default | | | |
| { | | | |
| typedef typename T1::elem_type eT; | | | |
| | | | |
| inline | | | |
| partial_unwrap_neg_default(const eOp<T1, eop_neg>& A) | | | |
| : M(A.P.Q) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT> M; | | | |
| }; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_neg_fixed | | | |
| { | | | |
| typedef typename T1::elem_type eT; | | | |
| | | | |
| inline explicit | | | |
| partial_unwrap_neg_fixed(const eOp<T1, eop_neg>& A) | | | |
| : M(A.P.Q) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| template<typename T1, bool condition> | | | |
| struct partial_unwrap_neg_redirect {}; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_neg_redirect<T1, false> { typedef partial_unwrap_neg_ | | | |
| default<T1> result; }; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_neg_redirect<T1, true> { typedef partial_unwrap_neg_ | | | |
| fixed<T1> result; }; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap< eOp<T1, eop_neg> > : public partial_unwrap_neg_redir | | | |
| ect<T1, is_Mat_fixed<T1>::value >::result | | | |
| { | | | |
| typedef typename T1::elem_type eT; | | | |
| | | | |
| inline | | | |
| partial_unwrap(const eOp<T1, eop_neg>& A) | | | |
| : partial_unwrap_neg_redirect< T1, is_Mat_fixed<T1>::value >::result(A) | | | |
| { | | | |
| } | | | |
| }; | | | |
| | | | |
| template<typename eT> | | | |
| struct partial_unwrap< eOp<Mat<eT>, eop_neg> > | | | |
| { | | | |
| inline | | | |
| partial_unwrap(const eOp<Mat<eT>,eop_neg>& A) | | | |
| : M(A.P.Q) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| template<typename eT> | | | |
| struct partial_unwrap< eOp<Row<eT>, eop_neg> > | | | |
| { | | | |
| inline | | | |
| partial_unwrap(const eOp<Row<eT>,eop_neg>& A) | | | |
| : M(A.P.Q) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| template<typename eT> | | | |
| struct partial_unwrap< eOp<Col<eT>, eop_neg> > | | | |
| { | | | |
| inline | | | |
| partial_unwrap(const eOp<Col<eT>,eop_neg>& A) | | | |
| : M(A.P.Q) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| // | | // | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| struct partial_unwrap_check_default | | struct partial_unwrap_check_default | |
| { | | { | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
| inline | | inline | |
| partial_unwrap_check_default(const T1& A, const Mat<eT>&) | | partial_unwrap_check_default(const T1& A, const Mat<eT>&) | |
| : M(A) | | : M(A) | |
| | | | |
| skipping to change at line 2029 | | skipping to change at line 1914 | |
| static const bool do_trans = false; | | static const bool do_trans = false; | |
| static const bool do_times = true; | | static const bool do_times = true; | |
| | | | |
| const eT val; | | const eT val; | |
| const Mat<eT> M; | | const Mat<eT> M; | |
| | | | |
| //// prevents the compiler from potentially deleting the subview object b
efore we're done with it | | //// prevents the compiler from potentially deleting the subview object b
efore we're done with it | |
| //const eOp<subview_col<eT>,eop_scalar_times>& ref; | | //const eOp<subview_col<eT>,eop_scalar_times>& ref; | |
| }; | | }; | |
| | | | |
|
| template<typename T1> | | | |
| struct partial_unwrap_check_neg_default | | | |
| { | | | |
| typedef typename T1::elem_type eT; | | | |
| | | | |
| inline | | | |
| partial_unwrap_check_neg_default(const eOp<T1, eop_neg>& A, const Mat<eT> | | | |
| &) | | | |
| : M(A.P.Q) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT> M; | | | |
| }; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_check_neg_fixed | | | |
| { | | | |
| typedef typename T1::elem_type eT; | | | |
| | | | |
| inline explicit | | | |
| partial_unwrap_check_neg_fixed(const eOp<T1, eop_neg>& A, const Mat<eT>& | | | |
| B) | | | |
| : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0 ) | | | |
| , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline | | | |
| ~partial_unwrap_check_neg_fixed() | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| if(M_local) { delete M_local; } | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>* M_local; | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| template<typename T1, bool condition> | | | |
| struct partial_unwrap_check_neg_redirect {}; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_check_neg_redirect<T1, false> { typedef partial_unwra | | | |
| p_check_neg_default<T1> result; }; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_check_neg_redirect<T1, true> { typedef partial_unwra | | | |
| p_check_neg_fixed<T1> result; }; | | | |
| | | | |
| template<typename T1> | | | |
| struct partial_unwrap_check< eOp<T1, eop_neg> > : public partial_unwrap_che | | | |
| ck_neg_redirect<T1, is_Mat_fixed<T1>::value >::result | | | |
| { | | | |
| typedef typename T1::elem_type eT; | | | |
| | | | |
| inline partial_unwrap_check(const eOp<T1, eop_neg>& A, const Mat<eT>& B) | | | |
| : partial_unwrap_check_neg_redirect< T1, is_Mat_fixed<T1>::value >::res | | | |
| ult(A, B) | | | |
| { | | | |
| } | | | |
| }; | | | |
| | | | |
| template<typename eT> | | | |
| struct partial_unwrap_check< eOp<Mat<eT>, eop_neg> > | | | |
| { | | | |
| arma_hot inline | | | |
| partial_unwrap_check(const eOp<Mat<eT>,eop_neg>& A, const Mat<eT>& B) | | | |
| : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0 ) | | | |
| , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline | | | |
| ~partial_unwrap_check() | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| if(M_local) { delete M_local; } | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>* M_local; | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| template<typename eT> | | | |
| struct partial_unwrap_check< eOp<Row<eT>, eop_neg> > | | | |
| { | | | |
| arma_hot inline | | | |
| partial_unwrap_check(const eOp<Row<eT>,eop_neg>& A, const Mat<eT>& B) | | | |
| : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0 ) | | | |
| , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline | | | |
| ~partial_unwrap_check() | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| if(M_local) { delete M_local; } | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>* M_local; | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| template<typename eT> | | | |
| struct partial_unwrap_check< eOp<Col<eT>, eop_neg> > | | | |
| { | | | |
| arma_hot inline | | | |
| partial_unwrap_check(const eOp<Col<eT>,eop_neg>& A, const Mat<eT>& B) | | | |
| : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0 ) | | | |
| , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| inline | | | |
| ~partial_unwrap_check() | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| if(M_local) { delete M_local; } | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT>* M_local; | | | |
| const Mat<eT>& M; | | | |
| }; | | | |
| | | | |
| // NOTE: we can get away with this shortcut as the partial_unwrap_check cla | | | |
| ss is only used by the glue_times class, | | | |
| // NOTE: which relies on partial_unwrap_check to check for aliasing | | | |
| template<typename eT> | | | |
| struct partial_unwrap_check< eOp<subview_col<eT>, eop_neg> > | | | |
| { | | | |
| arma_hot inline | | | |
| partial_unwrap_check(const eOp<subview_col<eT>,eop_neg>& A, const Mat<eT> | | | |
| & B) | | | |
| : M ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, 1, (&(A.P.Q.m) | | | |
| == &B), false ) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| } | | | |
| | | | |
| arma_hot arma_inline eT get_val() const { return eT(-1); } | | | |
| | | | |
| static const bool do_trans = false; | | | |
| static const bool do_times = true; | | | |
| | | | |
| const Mat<eT> M; | | | |
| }; | | | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 2 change blocks. |
| 301 lines changed or deleted | | 0 lines changed or added | |
|