source: mmcs/armadillo_bits/spglue_minus_meat.hpp @ 8ad4484

matrices
Last change on this file since 8ad4484 was 9dd61b1, checked in by rboet <rboet@…>, 9 years ago

Avance del proyecto 60%

  • Property mode set to 100644
File size: 4.2 KB
Line 
1// Copyright (C) 2012-2014 Ryan Curtin
2// Copyright (C) 2012-2014 Conrad Sanderson
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8
9//! \addtogroup spglue_minus
10//! @{
11
12
13
14template<typename T1, typename T2>
15arma_hot
16inline
17void
18spglue_minus::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_minus>& X)
19  {
20  arma_extra_debug_sigprint();
21 
22  typedef typename T1::elem_type eT;
23 
24  const SpProxy<T1> pa(X.A);
25  const SpProxy<T2> pb(X.B);
26 
27  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
28 
29  if(is_alias == false)
30    {
31    spglue_minus::apply_noalias(out, pa, pb);
32    }
33  else
34    {
35    SpMat<eT> tmp;
36    spglue_minus::apply_noalias(tmp, pa, pb);
37   
38    out.steal_mem(tmp);
39    }
40  }
41
42
43
44template<typename eT, typename T1, typename T2>
45arma_hot
46inline
47void
48spglue_minus::apply_noalias(SpMat<eT>& result, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
49  {
50  arma_extra_debug_sigprint();
51 
52  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "subtraction");
53 
54  if( (pa.get_n_nonzero() != 0) && (pb.get_n_nonzero() != 0) )
55    {
56    result.set_size(pa.get_n_rows(), pa.get_n_cols());
57   
58    // Resize memory to correct size.
59    result.mem_resize(n_unique(pa, pb, op_n_unique_sub()));
60   
61    // Now iterate across both matrices.
62    typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
63    typename SpProxy<T2>::const_iterator_type y_it = pb.begin();
64   
65    typename SpProxy<T1>::const_iterator_type x_end = pa.end();
66    typename SpProxy<T2>::const_iterator_type y_end = pb.end();
67   
68    uword cur_val = 0;
69    while((x_it != x_end) || (y_it != y_end))
70      {
71      if(x_it == y_it)
72        {
73        const eT val = (*x_it) - (*y_it);
74       
75        if(val != eT(0))
76          {
77          access::rw(result.values[cur_val]) = val;
78          access::rw(result.row_indices[cur_val]) = x_it.row();
79          ++access::rw(result.col_ptrs[x_it.col() + 1]);
80          ++cur_val;
81          }
82       
83        ++x_it;
84        ++y_it;
85        }
86      else
87        {
88        const uword x_it_row = x_it.row();
89        const uword x_it_col = x_it.col();
90       
91        const uword y_it_row = y_it.row();
92        const uword y_it_col = y_it.col();
93       
94        if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
95          {
96          const eT val = (*x_it);
97         
98          if(val != eT(0))
99            {
100            access::rw(result.values[cur_val]) = val;
101            access::rw(result.row_indices[cur_val]) = x_it_row;
102            ++access::rw(result.col_ptrs[x_it_col + 1]);
103            ++cur_val;
104            }
105           
106          ++x_it;
107          }
108        else
109          {
110          const eT val = (*y_it);
111         
112          if(val != eT(0))
113            {
114            access::rw(result.values[cur_val]) = -(val);  // take the negative
115            access::rw(result.row_indices[cur_val]) = y_it_row;
116            ++access::rw(result.col_ptrs[y_it_col + 1]);
117            ++cur_val;
118            }
119         
120          ++y_it;
121          }
122        }
123      }
124   
125    // Fix column pointers to be cumulative.
126    for(uword c = 1; c <= result.n_cols; ++c)
127      {
128      access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
129      }
130    }
131  else
132    {
133    if(pa.get_n_nonzero() == 0)
134      {
135      result = pb.Q;
136      result *= eT(-1);
137     
138      return;
139      }
140   
141    if(pb.get_n_nonzero() == 0)
142      {
143      result = pa.Q;
144      return;
145      }
146    }
147  }
148
149
150
151//
152//
153// spglue_minus2: scalar*(A - B)
154
155
156
157template<typename T1, typename T2>
158arma_hot
159inline
160void
161spglue_minus2::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_minus2>& X)
162  {
163  arma_extra_debug_sigprint();
164 
165  typedef typename T1::elem_type eT;
166 
167  const SpProxy<T1> pa(X.A);
168  const SpProxy<T2> pb(X.B);
169 
170  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
171 
172  if(is_alias == false)
173    {
174    spglue_minus::apply_noalias(out, pa, pb);
175    }
176  else
177    {
178    SpMat<eT> tmp;
179    spglue_minus::apply_noalias(tmp, pa, pb);
180   
181    out.steal_mem(tmp);
182    }
183 
184  out *= X.aux;
185  }
186
187
188
189//! @}
Note: See TracBrowser for help on using the repository browser.