GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Sparse-diag-op-defs.h
Go to the documentation of this file.
1 /* -*- C++ -*-
2 
3 Copyright (C) 2009-2017 Jason Riedy, Jaroslav Hajek
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if ! defined (octave_Sparse_diag_op_defs_h)
24 #define octave_Sparse_diag_op_defs_h 1
25 
26 #include "octave-config.h"
27 
28 // Matrix multiplication
29 
30 template <typename RT, typename DM, typename SM>
31 RT do_mul_dm_sm (const DM& d, const SM& a)
32 {
33  const octave_idx_type nr = d.rows ();
34  const octave_idx_type nc = d.cols ();
35 
36  const octave_idx_type a_nr = a.rows ();
37  const octave_idx_type a_nc = a.cols ();
38 
39  if (nc != a_nr)
40  octave::err_nonconformant ("operator *", nr, nc, a_nr, a_nc);
41 
42  RT r (nr, a_nc, a.nnz ());
43 
44  octave_idx_type l = 0;
45 
46  for (octave_idx_type j = 0; j < a_nc; j++)
47  {
48  r.xcidx (j) = l;
49  const octave_idx_type colend = a.cidx (j+1);
50  for (octave_idx_type k = a.cidx (j); k < colend; k++)
51  {
52  const octave_idx_type i = a.ridx (k);
53  if (i >= nr) break;
54  r.xdata (l) = d.dgelem (i) * a.data (k);
55  r.xridx (l) = i;
56  l++;
57  }
58  }
59 
60  r.xcidx (a_nc) = l;
61 
62  r.maybe_compress (true);
63  return r;
64 }
65 
66 template <typename RT, typename SM, typename DM>
67 RT do_mul_sm_dm (const SM& a, const DM& d)
68 {
69  const octave_idx_type nr = d.rows ();
70  const octave_idx_type nc = d.cols ();
71 
72  const octave_idx_type a_nr = a.rows ();
73  const octave_idx_type a_nc = a.cols ();
74 
75  if (nr != a_nc)
76  octave::err_nonconformant ("operator *", a_nr, a_nc, nr, nc);
77 
78  const octave_idx_type mnc = nc < a_nc ? nc: a_nc;
79  RT r (a_nr, nc, a.cidx (mnc));
80 
81  for (octave_idx_type j = 0; j < mnc; ++j)
82  {
83  const typename DM::element_type s = d.dgelem (j);
84  const octave_idx_type colend = a.cidx (j+1);
85  r.xcidx (j) = a.cidx (j);
86  for (octave_idx_type k = a.cidx (j); k < colend; ++k)
87  {
88  r.xdata (k) = s * a.data (k);
89  r.xridx (k) = a.ridx (k);
90  }
91  }
92  for (octave_idx_type j = mnc; j <= nc; ++j)
93  r.xcidx (j) = a.cidx (mnc);
94 
95  r.maybe_compress (true);
96  return r;
97 }
98 
99 // FIXME: functors such as this should be gathered somewhere
100 template <typename T>
102  : public std::unary_function <T, T>
103 {
104  T operator () (const T x) { return x; }
105 };
106 
107 // Matrix addition
108 
109 template <typename RT, typename SM, typename DM, typename OpA, typename OpD>
110 RT inner_do_add_sm_dm (const SM& a, const DM& d, OpA opa, OpD opd)
111 {
112  using std::min;
113  const octave_idx_type nr = d.rows ();
114  const octave_idx_type nc = d.cols ();
115  const octave_idx_type n = min (nr, nc);
116 
117  const octave_idx_type a_nr = a.rows ();
118  const octave_idx_type a_nc = a.cols ();
119 
120  const octave_idx_type nz = a.nnz ();
121  RT r (a_nr, a_nc, nz + n);
122  octave_idx_type k = 0;
123 
124  for (octave_idx_type j = 0; j < nc; ++j)
125  {
126  octave_quit ();
127  const octave_idx_type colend = a.cidx (j+1);
128  r.xcidx (j) = k;
129  octave_idx_type k_src = a.cidx (j), k_split;
130 
131  for (k_split = k_src; k_split < colend; k_split++)
132  if (a.ridx (k_split) >= j)
133  break;
134 
135  for (; k_src < k_split; k_src++, k++)
136  {
137  r.xridx (k) = a.ridx (k_src);
138  r.xdata (k) = opa (a.data (k_src));
139  }
140 
141  if (k_src < colend && a.ridx (k_src) == j)
142  {
143  r.xridx (k) = j;
144  r.xdata (k) = opa (a.data (k_src)) + opd (d.dgelem (j));
145  k++; k_src++;
146  }
147  else
148  {
149  r.xridx (k) = j;
150  r.xdata (k) = opd (d.dgelem (j));
151  k++;
152  }
153 
154  for (; k_src < colend; k_src++, k++)
155  {
156  r.xridx (k) = a.ridx (k_src);
157  r.xdata (k) = opa (a.data (k_src));
158  }
159 
160  }
161  r.xcidx (nc) = k;
162 
163  r.maybe_compress (true);
164  return r;
165 }
166 
167 template <typename RT, typename DM, typename SM>
168 RT do_commutative_add_dm_sm (const DM& d, const SM& a)
169 {
170  // Extra function to ensure this is only emitted once.
171  return inner_do_add_sm_dm<RT> (a, d,
174 }
175 
176 template <typename RT, typename DM, typename SM>
177 RT do_add_dm_sm (const DM& d, const SM& a)
178 {
179  if (a.rows () != d.rows () || a.cols () != d.cols ())
180  octave::err_nonconformant ("operator +",
181  d.rows (), d.cols (), a.rows (), a.cols ());
182  else
183  return do_commutative_add_dm_sm<RT> (d, a);
184 }
185 
186 template <typename RT, typename DM, typename SM>
187 RT do_sub_dm_sm (const DM& d, const SM& a)
188 {
189  if (a.rows () != d.rows () || a.cols () != d.cols ())
190  octave::err_nonconformant ("operator -",
191  d.rows (), d.cols (), a.rows (), a.cols ());
192 
193  return inner_do_add_sm_dm<RT> (a, d,
194  std::negate<typename SM::element_type> (),
196 }
197 
198 template <typename RT, typename SM, typename DM>
199 RT do_add_sm_dm (const SM& a, const DM& d)
200 {
201  if (a.rows () != d.rows () || a.cols () != d.cols ())
202  octave::err_nonconformant ("operator +",
203  a.rows (), a.cols (), d.rows (), d.cols ());
204 
205  return do_commutative_add_dm_sm<RT> (d, a);
206 }
207 
208 template <typename RT, typename SM, typename DM>
209 RT do_sub_sm_dm (const SM& a, const DM& d)
210 {
211  if (a.rows () != d.rows () || a.cols () != d.cols ())
212  octave::err_nonconformant ("operator -",
213  a.rows (), a.cols (), d.rows (), d.cols ());
214 
215  return inner_do_add_sm_dm<RT> (a, d,
217  std::negate<typename DM::element_type> ());
218 }
219 
220 #endif
RT do_commutative_add_dm_sm(const DM &d, const SM &a)
RT do_mul_sm_dm(const SM &a, const DM &d)
RT do_add_dm_sm(const DM &d, const SM &a)
for large enough k
Definition: lu.cc:606
RT do_sub_dm_sm(const DM &d, const SM &a)
s
Definition: file-io.cc:2682
octave_idx_type a_nc
Definition: sylvester.cc:72
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
octave_idx_type a_nr
Definition: sylvester.cc:71
RT do_add_sm_dm(const SM &a, const DM &d)
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
RT inner_do_add_sm_dm(const SM &a, const DM &d, OpA opa, OpD opd)
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
RT do_sub_sm_dm(const SM &a, const DM &d)
T operator()(const T x)
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:205
RT do_mul_dm_sm(const DM &d, const SM &a)