#ifndef __COO_H__ #define __COO_H__ #include /* * Compute B = A for COO matrix A, CSR matrix B * * * Input Arguments: * I n_row - number of rows in A * I n_col - number of columns in A * I nnz - number of nonzeros in A * I Ai[nnz(A)] - row indices * I Aj[nnz(A)] - column indices * T Ax[nnz(A)] - nonzeros * Output Arguments: * I Bp - row pointer * I Bj - column indices * T Bx - nonzeros * * Note: * Output arrays Bp, Bj, and Bx must be preallocated * * Note: * Input: row and column indices *are not* assumed to be ordered * * Note: duplicate entries are carried over to the CSR represention * * Complexity: Linear. Specifically O(nnz(A) + max(n_row,n_col)) * */ template void coo_tocsr(const I n_row, const I n_col, const I nnz, const I Ai[], const I Aj[], const T Ax[], I Bp[], I Bj[], T Bx[]) { //compute number of non-zero entries per row of A std::fill(Bp, Bp + n_row, 0); for (I n = 0; n < nnz; n++){ Bp[Ai[n]]++; } //cumsum the nnz per row to get Bp[] for(I i = 0, cumsum = 0; i < n_row; i++){ I temp = Bp[i]; Bp[i] = cumsum; cumsum += temp; } Bp[n_row] = nnz; //write Aj,Ax into Bj,Bx for(I n = 0; n < nnz; n++){ I row = Ai[n]; I dest = Bp[row]; Bj[dest] = Aj[n]; Bx[dest] = Ax[n]; Bp[row]++; } for(I i = 0, last = 0; i <= n_row; i++){ I temp = Bp[i]; Bp[i] = last; last = temp; } //now Bp,Bj,Bx form a CSR representation (with possible duplicates) } /* * Compute B += A for COO matrix A, dense matrix B * * Input Arguments: * I n_row - number of rows in A * I n_col - number of columns in A * npy_int64 nnz - number of nonzeros in A * I Ai[nnz(A)] - row indices * I Aj[nnz(A)] - column indices * T Ax[nnz(A)] - nonzeros * T Bx[n_row*n_col] - dense matrix * */ template void coo_todense(const I n_row, const I n_col, const npy_int64 nnz, const I Ai[], const I Aj[], const T Ax[], T Bx[], const int fortran) { if (!fortran) { for(npy_int64 n = 0; n < nnz; n++){ Bx[ (npy_intp)n_col * Ai[n] + Aj[n] ] += Ax[n]; } } else { for(npy_int64 n = 0; n < nnz; n++){ Bx[ (npy_intp)n_row * Aj[n] + Ai[n] ] += Ax[n]; } } } /* * Compute Y += A*X for COO matrix A and dense vectors X,Y * * * Input Arguments: * npy_int64 nnz - number of nonzeros in A * I Ai[nnz] - row indices * I Aj[nnz] - column indices * T Ax[nnz] - nonzero values * T Xx[n_col] - input vector * * Output Arguments: * T Yx[n_row] - output vector * * Notes: * Output array Yx must be preallocated * * Complexity: Linear. Specifically O(nnz(A)) * */ template void coo_matvec(const npy_int64 nnz, const I Ai[], const I Aj[], const T Ax[], const T Xx[], T Yx[]) { for(npy_int64 n = 0; n < nnz; n++){ Yx[Ai[n]] += Ax[n] * Xx[Aj[n]]; } } #endif