tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
mmult_sparse_tensor.h
1 // -*- mode: c++; fill-column: 80; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 /*
3  Copyright (c) 2010 Juan Jose Garcia Ripoll
4 
5  Tensor is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published
7  by the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Library General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #ifndef TENSOR_MMULT_SPARSE_TENSOR_H
21 #define TENSOR_MMULT_SPARSE_TENSOR_H
22 
24 // RAW ROUTINES FOR THE SPARSE-TENSOR PRODUCT
25 //
26 
27 template<typename elt_t>
28 static void
29 mult_sp_t(elt_t *dest,
30  const index *row_start, const index *column, const elt_t *matrix,
31  const elt_t *vector,
32  index i_len, index j_len, index k_len, index l_len)
33 {
34  if (k_len == 1) {
35 #if 0
36  // dest(i,l) = matrix(i,j) vector(j,l)
37  for (; l_len; l_len--, vector+=j_len) {
38  for (index i = 0; i < i_len; i++) {
39  elt_t accum = *dest;
40  for (index j = row_start[i]; j < row_start[i+1]; j++) {
41  accum += matrix[j] * vector[column[j]];
42  }
43  *(dest++) = accum;
44  }
45  }
46 #else
47  for (; l_len; l_len--, vector+=j_len) {
48  const elt_t *m = matrix;
49  const index *c = column;
50  for (index i = 0; i < i_len; i++) {
51  elt_t accum = *dest;
52  for (index j = row_start[i+1] - row_start[i]; j; j--) {
53  accum += *(m++) * vector[*(c++)];
54  }
55  *(dest++) = accum;
56  }
57  }
58 #endif
59  } else {
60  // dest(i,k,l) = matrix(i,j) vector(k,j,l)
61  for (index l = 0; l < l_len; l++) {
62  const elt_t *v = vector + l*(k_len*j_len);
63  for (index k = 0; k < k_len; k++, v++) {
64  for (index i = 0; i < i_len; i++) {
65  elt_t accum = *dest;
66  for (index j = row_start[i]; j < row_start[i+1]; j++) {
67  accum += matrix[j] * v[column[j] * k_len];
68  }
69  *(dest++) = accum;
70  }
71  }
72  }
73  }
74 }
75 
77 // HIGHER LEVEL INTERFACE
78 //
79 
80 template<typename elt_t>
81 static inline const Tensor<elt_t>
82 do_mmult(const Sparse<elt_t> &m1, const Tensor<elt_t> &m2)
83 {
84  Indices dims(m2.rank());
85  index l_len = 1;
86  for (index k = 1, N = m2.rank(); k < N; k++) {
87  dims.at(k) = m2.dimension(k);
88  l_len *= dims[k];
89  }
90  index j_len = m2.dimension(0);
91  index i_len = dims.at(0) = m1.rows();
92 
93  if (j_len != m1.columns()) {
94  std::cerr <<
95  "In mmult(S,T), the first index of tensor T does not match the number of\n"
96  "columns in sparse matrix S.";
97  abort();
98  }
99 
100  Tensor<elt_t> output = Tensor<elt_t>::zeros(dims);
101 
102  mult_sp_t<elt_t>(output.begin(),
103  m1.priv_row_start().begin(), m1.priv_column().begin(),
104  m1.priv_data().begin(),
105  m2.begin(),
106  i_len, j_len, 1, l_len);
107 
108  return output;
109 }
110 
111 #endif /* !TENSOR_MMULT_SPARSE_TENSOR_H */
static const Tensor< elt_t > zeros(index rows)
Matrix of zeros.
Definition: tensor.h:235