Ejemplo n.º 1
0
 const Sparse<T> operator-(const Sparse<T> &s)
 {
   Vector<T> data(s.priv_data().size());
   std::transform(s.priv_data().begin(), s.priv_data().end(),
                  data.begin(), std::negate<T>());
   return Sparse<T>(s.dimensions(), s.priv_row_start(), s.priv_column(),
                    data);
 }
Ejemplo n.º 2
0
 const Sparse<T> operator/(const Sparse<T> &s, T b)
 {
   Vector<T> data(s.priv_data().size());
   std::transform(s.priv_data().begin(), s.priv_data().end(),
                  data.begin(), divided_constant<T,T>(b));
   return Sparse<T>(s.dimensions(), s.priv_row_start(), s.priv_column(),
                    data);
 }
Ejemplo n.º 3
0
  static const Sparse<elt_t> do_kron(const Sparse<elt_t> &s2, const Sparse<elt_t> &s1)
  {
    index rows1 = s1.rows();
    index cols1 = s1.columns();
    index rows2 = s2.rows();
    index cols2 = s2.columns();
    index number_nonzero = s1.length() * s2.length();
    index total_rows = rows1 * rows2;
    index total_cols = cols1 * cols2;

    if (number_nonzero == 0)
      return Sparse<elt_t>(total_rows, total_cols);

    Tensor<elt_t> output_data(number_nonzero);
    Indices output_column(number_nonzero);
    Indices output_row_start(total_rows+1);
    Indices output_dims(igen << total_rows << total_cols);

    typename Tensor<elt_t>::iterator out_data = output_data.begin();
    typename Indices::iterator out_column = output_column.begin();
    typename Indices::iterator out_begin = out_column;
    typename Indices::iterator out_row_start = output_row_start.begin();

    // C([i,j],[k,l]) = s1(i,k) s2(j,l)
    *(out_row_start++) = 0;
    for (index l = 0; l < rows2; l++) {
      for (index k = 0; k < rows1; k++) {
	for (index j = s2.priv_row_start()[l]; j < s2.priv_row_start()[l+1]; j++) {
	  for (index i = s1.priv_row_start()[k]; i < s1.priv_row_start()[k+1]; i++) {
	    *(out_data++) = s1.priv_data()[i] * s2.priv_data()[j];
	    *(out_column++) = s1.priv_column()[i] + cols1 * s2.priv_column()[j];
	  }
	}
	*(out_row_start++) = out_column - out_begin;
      }
    }
    return Sparse<elt_t>(output_dims, output_row_start, output_column, output_data);
  }
Ejemplo n.º 4
0
  const Sparse<T> sparse_binop(const Sparse<T> &m1, const Sparse<T> &m2,
                               binop op)
  {
    size_t rows = m1.rows();
    size_t cols = m1.columns();

    assert(rows == m2.rows() && cols == m2.columns());

    if (rows == 0 || cols == 0)
      return m1;

    index max_size = m1.priv_data().size() + m2.priv_data().size();
    Vector<T> data(max_size);
    Indices column(max_size);
    Indices row_start(rows + 1);

    typename Vector<T>::iterator out_data = data.begin();
    typename Indices::iterator out_column = column.begin();
    typename Indices::iterator out_row_start = row_start.begin();
    typename Vector<T>::iterator out_begin = out_data;

    typename Vector<T>::const_iterator m1_data = m1.priv_data().begin();
    typename Indices::const_iterator m1_row_start = m1.priv_row_start().begin();
    typename Indices::const_iterator m1_column = m1.priv_column().begin();

    typename Vector<T>::const_iterator m2_data = m2.priv_data().begin();
    typename Indices::const_iterator m2_row_start = m2.priv_row_start().begin();
    typename Indices::const_iterator m2_column = m2.priv_column().begin();

    index j1 = *(m1_row_start++);    // data start for this row in M1
    index l1 = (*m1_row_start) - j1; // # elements in this row in M1
    index j2 = *(m2_row_start++);    // data start for this row in M2
    index l2 = (*m2_row_start) - j2; // # elements in this row in M2
    *out_row_start = 0;
    while (1) {
      // We look for the next unprocessed matrix element on this row,
      // for both matrices. c1 and c2 are the columns associated to
      // each element on each matrix.
      index c1 = l1 ? *m1_column : cols;
      index c2 = l2 ? *m2_column : cols;
      T value;
      index c;
      if (c1 < c2) {
        // There is an element a column c1 on matrix m1, but the
        // same element at m2 is zero
        value = op(*m1_data, number_zero<T>());
        c = c1;
        l1--; m1_column++; m1_data++;
      } else if (c2 < c1) {
        // There is an element a column c2 on matrix m2, but the
        // same element at m1 is zero
        value = op(number_zero<T>(), *m2_data);
        c = c2;
        l2--; m2_column++; m2_data++;
      } else if (c2 < cols) {
        // Both elements in m1 and m2 are nonzero.
        value = op(*m1_data, *m2_data);
        c = c1;
        l1--; l2--;
        m1_column++; m1_data++;
        m2_column++; m2_data++;
      } else {
        // We have processed all elements in this row.
        out_row_start++;
        *out_row_start = out_data - out_begin;
        if (--rows == 0) {
          break;
        }
        j1 = *m1_row_start; m1_row_start++; l1 = (*m1_row_start) - j1;
        j2 = *m2_row_start; m2_row_start++; l2 = (*m2_row_start) - j2;
        continue;
      }
      if (!(value == number_zero<T>())) {
        *(out_data++) = value;
        *(out_column++) = c;
      }
    }
    index j = out_data - out_begin;
    Indices the_column(j);
    std::copy(column.begin(), column.begin() + j, the_column.begin());
    Vector<T> the_data(j);
    std::copy(data.begin(), data.begin() + j, the_data.begin());
    return Sparse<T>(m1.dimensions(), row_start, the_column, the_data);
  }