Skip to content

apply

Implements matrix multiplication of a sparse matrix \(A\) in compressed-sparse-row (CSR) format with a vector \(x\) or a matrix \(X\),

\[ y = Ax, \quad Y = AX. \]

Sources
apply.hpp
apply.cpp
apply.jl


There are two interfaces to perform this operation.

  1. The new vector \(y\) or or matrix \(Y\) is allocated internally and returned.

    template <typename idx_t, typename coeff_t>
    arma::Col<coeff_t> apply(CSRMatrix<idx_t, coeff_t> const &A, arma::Col<coeff_t> const &x);
    template <typename idx_t, typename coeff_t>
    arma::Col<coeff_t> apply(CSRMatrix<idx_t, coeff_t> const &A, arma::Mat<coeff_t> const &X);
    
    apply(A::CSRMatrix{IdxT, CoeffT}, x::Vector{CoeffT})
    apply(A::CSRMatrix{IdxT, CoeffT}, X::Matrix{CoeffT})
    
  2. The return vector \(y\) or matrix \(Y\) has already been allocated, is given as an agrument to the apply function, where it is overwritten.

    template <typename idx_t, typename coeff_t>
    void apply(CSRMatrix<idx_t, coeff_t> const &A, arma::Col<coeff_t> const &x, arma::Col<coeff_t> &y);
    template <typename idx_t, typename coeff_t>
    void apply(CSRMatrix<idx_t, coeff_t> const &A, arma::Mat<coeff_t> const &X, arma::Mat<coeff_t> &Y);
    
    apply(A::CSRMatrix{IdxT, CoeffT}, x::Vector{CoeffT}, y::Vector{CoeffT})
    apply(A::CSRMatrix{IdxT, CoeffT}, X::Matrix{CoeffT}, Y::Matrix{CoeffT})
    

Parameters

Name Description
A sparse matrix in compressed-sparse-row (CSR)format, see sparse matrix types
x, X Input vector or matrix
y, Y Output vector or matrix

Comment XDiag only provides sparse matrix-vector and matrix-matrix multiplication functionality for CSR matrices, as these can be efficiently parallelized. When linking to the Intel MKL library in the C++ version, specialized sparse BLAS routines are called to improve performance.


Usage Example

// Real vector apply
{
  int N = 8;
  auto block = Spinhalf(N,  N / 2);
  auto ops = OpSum();
  for (int i=0; i<N; ++i){
    ops += Op("SdotS", {i, (i+1)%N});
  }
  auto spmat = csr_matrix(ops, block);
  auto rstate = random_state(block);
  arma::vec res = apply(spmat, rstate.vector(false));
}

// Complex matrix apply
{
   int N = 4;
   auto block = Electron(N,  N / 2, N / 2);
   auto ops = OpSum();
   for (int i=0; i<N; ++i){
     ops += complex(1.0, 1.0) * Op("Hop", {i, (i+1)%N});
   }
  auto spmat = csr_matrixC(ops, block);
  int64_t ncols = 3;
  auto rstate = random_state(block, false, ncols);
  arma::cx_mat in = rstate.matrixC();
  arma::cx_mat out(block.size(), ncols, arma::fill::zeros);
  apply(spmat, in, out);
}
let
    # Real vector apply
    N = 8
    block = Spinhalf(N,  N ÷ 2)
    ops = OpSum()
    for i in 1:N
        ops += Op("SdotS", [i, mod1(i+1, N)])
    end
    spmat = csr_matrix(ops, block)
    rstate = random_state(block)
    res = apply(spmat, vector(rstate))

    # Complex matrix apply
    N = 4
    block = Electron(N,  N ÷ 2, N ÷ 2)
    ops = OpSum()
    for i in 1:N
        ops += (1.0 + 1.0im) * Op("Hop", [i, mod1(i+1, N)])
    end
    spmat = csr_matrix(ops, block)
    ncols = 3
    rstate = random_state(block; real=false, ncols=ncols)
    in = matrix(rstate)
    out = zeros(ComplexF64, size(block), ncols)
    apply(spmat, in, out)
end