Mercurial > hg > octave-thorsten
annotate liboctave/Sparse.cc @ 9469:c6edba80dfae
sanity checks for loading sparse matrices
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 29 Jul 2009 12:15:27 -0400 |
parents | 39be2c4531c8 |
children | 829e69ec3110 |
rev | line source |
---|---|
5164 | 1 // Template sparse array class |
2 /* | |
3 | |
8920 | 4 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman |
7016 | 5 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler |
6 | |
7 This file is part of Octave. | |
5164 | 8 |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
7016 | 11 Free Software Foundation; either version 3 of the License, or (at your |
12 option) any later version. | |
5164 | 13 |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
7016 | 20 along with Octave; see the file COPYING. If not, see |
21 <http://www.gnu.org/licenses/>. | |
5164 | 22 |
23 */ | |
24 | |
25 #ifdef HAVE_CONFIG_H | |
26 #include <config.h> | |
27 #endif | |
28 | |
29 #include <cassert> | |
30 #include <climits> | |
31 | |
32 #include <iostream> | |
5765 | 33 #include <sstream> |
5164 | 34 #include <vector> |
35 | |
36 #include "Array.h" | |
37 #include "Array-util.h" | |
38 #include "Range.h" | |
39 #include "idx-vector.h" | |
40 #include "lo-error.h" | |
41 #include "quit.h" | |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
8290
diff
changeset
|
42 #include "oct-locbuf.h" |
5164 | 43 |
44 #include "Sparse.h" | |
45 #include "sparse-sort.h" | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
46 #include "sparse-util.h" |
5164 | 47 #include "oct-spparms.h" |
48 | |
49 template <class T> | |
50 T& | |
5275 | 51 Sparse<T>::SparseRep::elem (octave_idx_type _r, octave_idx_type _c) |
5164 | 52 { |
5275 | 53 octave_idx_type i; |
5164 | 54 |
5604 | 55 if (nzmx > 0) |
5164 | 56 { |
57 for (i = c[_c]; i < c[_c + 1]; i++) | |
58 if (r[i] == _r) | |
59 return d[i]; | |
60 else if (r[i] > _r) | |
61 break; | |
62 | |
63 // Ok, If we've gotten here, we're in trouble.. Have to create a | |
64 // new element in the sparse array. This' gonna be slow!!! | |
5869 | 65 if (c[ncols] == nzmx) |
5164 | 66 { |
67 (*current_liboctave_error_handler) | |
5275 | 68 ("Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled"); |
5164 | 69 return *d; |
70 } | |
71 | |
5275 | 72 octave_idx_type to_move = c[ncols] - i; |
5164 | 73 if (to_move != 0) |
74 { | |
5275 | 75 for (octave_idx_type j = c[ncols]; j > i; j--) |
5164 | 76 { |
77 d[j] = d[j-1]; | |
78 r[j] = r[j-1]; | |
79 } | |
80 } | |
81 | |
5275 | 82 for (octave_idx_type j = _c + 1; j < ncols + 1; j++) |
5164 | 83 c[j] = c[j] + 1; |
84 | |
85 d[i] = 0.; | |
86 r[i] = _r; | |
87 | |
88 return d[i]; | |
89 } | |
90 else | |
91 { | |
92 (*current_liboctave_error_handler) | |
5275 | 93 ("Sparse::SparseRep::elem (octave_idx_type, octave_idx_type): sparse matrix filled"); |
5164 | 94 return *d; |
95 } | |
96 } | |
97 | |
98 template <class T> | |
99 T | |
5275 | 100 Sparse<T>::SparseRep::celem (octave_idx_type _r, octave_idx_type _c) const |
5164 | 101 { |
5604 | 102 if (nzmx > 0) |
5275 | 103 for (octave_idx_type i = c[_c]; i < c[_c + 1]; i++) |
5164 | 104 if (r[i] == _r) |
105 return d[i]; | |
106 return T (); | |
107 } | |
108 | |
109 template <class T> | |
110 void | |
111 Sparse<T>::SparseRep::maybe_compress (bool remove_zeros) | |
112 { | |
5604 | 113 octave_idx_type ndel = nzmx - c[ncols]; |
5275 | 114 octave_idx_type nzero = 0; |
5164 | 115 |
116 if (remove_zeros) | |
5604 | 117 for (octave_idx_type i = 0; i < nzmx - ndel; i++) |
5164 | 118 if (d[i] == T ()) |
119 nzero++; | |
120 | |
121 if (!ndel && !nzero) | |
122 return; | |
123 | |
124 if (!nzero) | |
125 { | |
5604 | 126 octave_idx_type new_nzmx = nzmx - ndel; |
127 | |
128 T *new_data = new T [new_nzmx]; | |
129 for (octave_idx_type i = 0; i < new_nzmx; i++) | |
5164 | 130 new_data[i] = d[i]; |
131 delete [] d; | |
132 d = new_data; | |
133 | |
5604 | 134 octave_idx_type *new_ridx = new octave_idx_type [new_nzmx]; |
135 for (octave_idx_type i = 0; i < new_nzmx; i++) | |
5164 | 136 new_ridx[i] = r[i]; |
137 delete [] r; | |
138 r = new_ridx; | |
139 } | |
140 else | |
141 { | |
5604 | 142 octave_idx_type new_nzmx = nzmx - ndel - nzero; |
143 | |
144 T *new_data = new T [new_nzmx]; | |
145 octave_idx_type *new_ridx = new octave_idx_type [new_nzmx]; | |
5275 | 146 |
147 octave_idx_type ii = 0; | |
148 octave_idx_type ic = 0; | |
149 for (octave_idx_type j = 0; j < ncols; j++) | |
5164 | 150 { |
5275 | 151 for (octave_idx_type k = ic; k < c[j+1]; k++) |
5164 | 152 if (d[k] != T ()) |
153 { | |
154 new_data [ii] = d[k]; | |
155 new_ridx [ii++] = r[k]; | |
156 } | |
157 ic = c[j+1]; | |
158 c[j+1] = ii; | |
159 } | |
160 | |
161 delete [] d; | |
162 d = new_data; | |
163 | |
164 delete [] r; | |
165 r = new_ridx; | |
166 } | |
167 | |
5604 | 168 nzmx -= ndel + nzero; |
5164 | 169 } |
170 | |
171 template <class T> | |
172 void | |
5275 | 173 Sparse<T>::SparseRep::change_length (octave_idx_type nz) |
5164 | 174 { |
5604 | 175 if (nz != nzmx) |
5164 | 176 { |
5604 | 177 octave_idx_type min_nzmx = (nz < nzmx ? nz : nzmx); |
5275 | 178 |
179 octave_idx_type * new_ridx = new octave_idx_type [nz]; | |
5604 | 180 for (octave_idx_type i = 0; i < min_nzmx; i++) |
5164 | 181 new_ridx[i] = r[i]; |
182 | |
183 delete [] r; | |
184 r = new_ridx; | |
185 | |
186 T * new_data = new T [nz]; | |
5604 | 187 for (octave_idx_type i = 0; i < min_nzmx; i++) |
5164 | 188 new_data[i] = d[i]; |
189 | |
190 delete [] d; | |
191 d = new_data; | |
192 | |
5604 | 193 if (nz < nzmx) |
5275 | 194 for (octave_idx_type i = 0; i <= ncols; i++) |
5164 | 195 if (c[i] > nz) |
196 c[i] = nz; | |
197 | |
5604 | 198 nzmx = nz; |
5164 | 199 } |
200 } | |
201 | |
202 template <class T> | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
203 bool |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
204 Sparse<T>::SparseRep::indices_ok (void) const |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
205 { |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
206 return sparse_indices_ok (r, c, nrows, ncols, nnz ()); |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
207 } |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
208 |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9177
diff
changeset
|
209 template <class T> |
5164 | 210 template <class U> |
211 Sparse<T>::Sparse (const Sparse<U>& a) | |
212 : dimensions (a.dimensions), idx (0), idx_count (0) | |
213 { | |
5681 | 214 if (a.nnz () == 0) |
5164 | 215 rep = new typename Sparse<T>::SparseRep (rows (), cols()); |
216 else | |
217 { | |
5681 | 218 rep = new typename Sparse<T>::SparseRep (rows (), cols (), a.nnz ()); |
5164 | 219 |
5681 | 220 octave_idx_type nz = a.nnz (); |
5275 | 221 octave_idx_type nc = cols (); |
222 for (octave_idx_type i = 0; i < nz; i++) | |
5164 | 223 { |
224 xdata (i) = T (a.data (i)); | |
225 xridx (i) = a.ridx (i); | |
226 } | |
5275 | 227 for (octave_idx_type i = 0; i < nc + 1; i++) |
5164 | 228 xcidx (i) = a.cidx (i); |
229 } | |
230 } | |
231 | |
232 template <class T> | |
5275 | 233 Sparse<T>::Sparse (octave_idx_type nr, octave_idx_type nc, T val) |
5630 | 234 : dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) |
5164 | 235 { |
5630 | 236 if (val != T ()) |
5164 | 237 { |
5630 | 238 rep = new typename Sparse<T>::SparseRep (nr, nc, nr*nc); |
239 | |
240 octave_idx_type ii = 0; | |
241 xcidx (0) = 0; | |
242 for (octave_idx_type j = 0; j < nc; j++) | |
5164 | 243 { |
5630 | 244 for (octave_idx_type i = 0; i < nr; i++) |
245 { | |
246 xdata (ii) = val; | |
247 xridx (ii++) = i; | |
248 } | |
249 xcidx (j+1) = ii; | |
250 } | |
251 } | |
252 else | |
253 { | |
254 rep = new typename Sparse<T>::SparseRep (nr, nc, 0); | |
255 for (octave_idx_type j = 0; j < nc+1; j++) | |
256 xcidx(j) = 0; | |
5164 | 257 } |
258 } | |
259 | |
260 template <class T> | |
261 Sparse<T>::Sparse (const dim_vector& dv) | |
262 : dimensions (dv), idx (0), idx_count (0) | |
263 { | |
264 if (dv.length() != 2) | |
265 (*current_liboctave_error_handler) | |
266 ("Sparse::Sparse (const dim_vector&): dimension mismatch"); | |
267 else | |
268 rep = new typename Sparse<T>::SparseRep (dv(0), dv(1)); | |
269 } | |
270 | |
271 template <class T> | |
272 Sparse<T>::Sparse (const Sparse<T>& a, const dim_vector& dv) | |
273 : dimensions (dv), idx (0), idx_count (0) | |
274 { | |
275 | |
276 // Work in unsigned long long to avoid overflow issues with numel | |
277 unsigned long long a_nel = static_cast<unsigned long long>(a.rows ()) * | |
278 static_cast<unsigned long long>(a.cols ()); | |
279 unsigned long long dv_nel = static_cast<unsigned long long>(dv (0)) * | |
280 static_cast<unsigned long long>(dv (1)); | |
281 | |
282 if (a_nel != dv_nel) | |
283 (*current_liboctave_error_handler) | |
284 ("Sparse::Sparse (const Sparse&, const dim_vector&): dimension mismatch"); | |
285 else | |
286 { | |
287 dim_vector old_dims = a.dims(); | |
5681 | 288 octave_idx_type new_nzmx = a.nnz (); |
5275 | 289 octave_idx_type new_nr = dv (0); |
290 octave_idx_type new_nc = dv (1); | |
291 octave_idx_type old_nr = old_dims (0); | |
292 octave_idx_type old_nc = old_dims (1); | |
5164 | 293 |
5604 | 294 rep = new typename Sparse<T>::SparseRep (new_nr, new_nc, new_nzmx); |
5164 | 295 |
5275 | 296 octave_idx_type kk = 0; |
5164 | 297 xcidx(0) = 0; |
5275 | 298 for (octave_idx_type i = 0; i < old_nc; i++) |
299 for (octave_idx_type j = a.cidx(i); j < a.cidx(i+1); j++) | |
5164 | 300 { |
5275 | 301 octave_idx_type tmp = i * old_nr + a.ridx(j); |
302 octave_idx_type ii = tmp % new_nr; | |
303 octave_idx_type jj = (tmp - ii) / new_nr; | |
304 for (octave_idx_type k = kk; k < jj; k++) | |
5164 | 305 xcidx(k+1) = j; |
306 kk = jj; | |
307 xdata(j) = a.data(j); | |
308 xridx(j) = ii; | |
309 } | |
5275 | 310 for (octave_idx_type k = kk; k < new_nc; k++) |
5604 | 311 xcidx(k+1) = new_nzmx; |
5164 | 312 } |
313 } | |
314 | |
315 template <class T> | |
5275 | 316 Sparse<T>::Sparse (const Array<T>& a, const Array<octave_idx_type>& r, |
317 const Array<octave_idx_type>& c, octave_idx_type nr, | |
318 octave_idx_type nc, bool sum_terms) | |
5164 | 319 : dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) |
320 { | |
5275 | 321 octave_idx_type a_len = a.length (); |
322 octave_idx_type r_len = r.length (); | |
323 octave_idx_type c_len = c.length (); | |
5164 | 324 bool ri_scalar = (r_len == 1); |
325 bool ci_scalar = (c_len == 1); | |
326 bool cf_scalar = (a_len == 1); | |
327 | |
328 if ((a_len != r_len && !cf_scalar && !ri_scalar) || | |
329 (a_len != c_len && !cf_scalar && !ci_scalar) || | |
330 (r_len != c_len && !ri_scalar && !ci_scalar) || nr < 0 || nc < 0) | |
331 { | |
332 (*current_liboctave_error_handler) | |
5275 | 333 ("Sparse::Sparse (const Array<T>&, const Array<octave_idx_type>&, ...): dimension mismatch"); |
5164 | 334 rep = nil_rep (); |
335 dimensions = dim_vector (0, 0); | |
336 } | |
337 else | |
338 { | |
5604 | 339 octave_idx_type max_nzmx = (r_len > c_len ? r_len : c_len); |
340 | |
341 OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl *, sidx, max_nzmx); | |
342 OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl, sidxX, max_nzmx); | |
343 | |
344 for (octave_idx_type i = 0; i < max_nzmx; i++) | |
5164 | 345 sidx[i] = &sidxX[i]; |
346 | |
5604 | 347 octave_idx_type actual_nzmx = 0; |
5164 | 348 OCTAVE_QUIT; |
5604 | 349 for (octave_idx_type i = 0; i < max_nzmx; i++) |
5164 | 350 { |
5275 | 351 octave_idx_type rowidx = (ri_scalar ? r(0) : r(i)); |
352 octave_idx_type colidx = (ci_scalar ? c(0) : c(i)); | |
5164 | 353 if (rowidx < nr && rowidx >= 0 && |
354 colidx < nc && colidx >= 0 ) | |
355 { | |
356 if ( a (cf_scalar ? 0 : i ) != T ()) | |
357 { | |
5604 | 358 sidx[actual_nzmx]->r = rowidx; |
359 sidx[actual_nzmx]->c = colidx; | |
360 sidx[actual_nzmx]->idx = i; | |
361 actual_nzmx++; | |
5164 | 362 } |
363 } | |
364 else | |
365 { | |
366 (*current_liboctave_error_handler) | |
367 ("Sparse::Sparse : index (%d,%d) out of range", | |
368 rowidx + 1, colidx + 1); | |
369 rep = nil_rep (); | |
370 dimensions = dim_vector (0, 0); | |
371 return; | |
372 } | |
373 } | |
374 | |
5604 | 375 if (actual_nzmx == 0) |
5164 | 376 rep = new typename Sparse<T>::SparseRep (nr, nc); |
377 else | |
378 { | |
379 OCTAVE_QUIT; | |
380 octave_sort<octave_sparse_sort_idxl *> | |
7433 | 381 lsort (octave_sparse_sidxl_comp); |
382 | |
383 lsort.sort (sidx, actual_nzmx); | |
5164 | 384 OCTAVE_QUIT; |
385 | |
386 // Now count the unique non-zero values | |
5604 | 387 octave_idx_type real_nzmx = 1; |
388 for (octave_idx_type i = 1; i < actual_nzmx; i++) | |
5164 | 389 if (sidx[i-1]->r != sidx[i]->r || sidx[i-1]->c != sidx[i]->c) |
5604 | 390 real_nzmx++; |
391 | |
392 rep = new typename Sparse<T>::SparseRep (nr, nc, real_nzmx); | |
5164 | 393 |
5275 | 394 octave_idx_type cx = 0; |
395 octave_idx_type prev_rval = -1; | |
396 octave_idx_type prev_cval = -1; | |
397 octave_idx_type ii = -1; | |
5164 | 398 xcidx (0) = 0; |
5604 | 399 for (octave_idx_type i = 0; i < actual_nzmx; i++) |
5164 | 400 { |
401 OCTAVE_QUIT; | |
5275 | 402 octave_idx_type iidx = sidx[i]->idx; |
403 octave_idx_type rval = sidx[i]->r; | |
404 octave_idx_type cval = sidx[i]->c; | |
5164 | 405 |
406 if (prev_cval < cval || (prev_rval < rval && prev_cval == cval)) | |
407 { | |
5275 | 408 octave_idx_type ci = static_cast<octave_idx_type> (c (ci_scalar ? 0 : iidx)); |
5164 | 409 ii++; |
410 while (cx < ci) | |
411 xcidx (++cx) = ii; | |
412 xdata(ii) = a (cf_scalar ? 0 : iidx); | |
5275 | 413 xridx(ii) = static_cast<octave_idx_type> (r (ri_scalar ? 0 : iidx)); |
5164 | 414 } |
415 else | |
416 { | |
417 if (sum_terms) | |
418 xdata(ii) += a (cf_scalar ? 0 : iidx); | |
419 else | |
420 xdata(ii) = a (cf_scalar ? 0 : iidx); | |
421 } | |
422 prev_rval = rval; | |
423 prev_cval = cval; | |
424 } | |
425 | |
426 while (cx < nc) | |
427 xcidx (++cx) = ii + 1; | |
428 } | |
429 } | |
430 } | |
431 | |
432 template <class T> | |
433 Sparse<T>::Sparse (const Array<T>& a, const Array<double>& r, | |
5275 | 434 const Array<double>& c, octave_idx_type nr, |
435 octave_idx_type nc, bool sum_terms) | |
5164 | 436 : dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) |
437 { | |
5275 | 438 octave_idx_type a_len = a.length (); |
439 octave_idx_type r_len = r.length (); | |
440 octave_idx_type c_len = c.length (); | |
5164 | 441 bool ri_scalar = (r_len == 1); |
442 bool ci_scalar = (c_len == 1); | |
443 bool cf_scalar = (a_len == 1); | |
444 | |
445 if ((a_len != r_len && !cf_scalar && !ri_scalar) || | |
446 (a_len != c_len && !cf_scalar && !ci_scalar) || | |
447 (r_len != c_len && !ri_scalar && !ci_scalar) || nr < 0 || nc < 0) | |
448 { | |
449 (*current_liboctave_error_handler) | |
450 ("Sparse::Sparse (const Array<T>&, const Array<double>&, ...): dimension mismatch"); | |
451 rep = nil_rep (); | |
452 dimensions = dim_vector (0, 0); | |
453 } | |
454 else | |
455 { | |
5604 | 456 octave_idx_type max_nzmx = (r_len > c_len ? r_len : c_len); |
5164 | 457 |
5604 | 458 OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl *, sidx, max_nzmx); |
459 OCTAVE_LOCAL_BUFFER (octave_sparse_sort_idxl, sidxX, max_nzmx); | |
460 | |
461 for (octave_idx_type i = 0; i < max_nzmx; i++) | |
5164 | 462 sidx[i] = &sidxX[i]; |
463 | |
5604 | 464 octave_idx_type actual_nzmx = 0; |
5164 | 465 OCTAVE_QUIT; |
466 | |
5604 | 467 for (octave_idx_type i = 0; i < max_nzmx; i++) |
5164 | 468 { |
5275 | 469 octave_idx_type rowidx = static_cast<octave_idx_type> (ri_scalar ? r(0) : r(i)); |
470 octave_idx_type colidx = static_cast<octave_idx_type> (ci_scalar ? c(0) : c(i)); | |
5164 | 471 if (rowidx < nr && rowidx >= 0 && |
472 colidx < nc && colidx >= 0 ) | |
473 { | |
474 if ( a (cf_scalar ? 0 : i ) != T ()) | |
475 { | |
5604 | 476 sidx[actual_nzmx]->r = rowidx; |
477 sidx[actual_nzmx]->c = colidx; | |
478 sidx[actual_nzmx]->idx = i; | |
479 actual_nzmx++; | |
5164 | 480 } |
481 } | |
482 else | |
483 { | |
484 (*current_liboctave_error_handler) | |
485 ("Sparse::Sparse : index (%d,%d) out of range", | |
486 rowidx + 1, colidx + 1); | |
487 rep = nil_rep (); | |
488 dimensions = dim_vector (0, 0); | |
489 return; | |
490 } | |
491 } | |
492 | |
5604 | 493 if (actual_nzmx == 0) |
5164 | 494 rep = new typename Sparse<T>::SparseRep (nr, nc); |
495 else | |
496 { | |
497 OCTAVE_QUIT; | |
498 octave_sort<octave_sparse_sort_idxl *> | |
7433 | 499 lsort (octave_sparse_sidxl_comp); |
500 | |
501 lsort.sort (sidx, actual_nzmx); | |
5164 | 502 OCTAVE_QUIT; |
503 | |
504 // Now count the unique non-zero values | |
5604 | 505 octave_idx_type real_nzmx = 1; |
506 for (octave_idx_type i = 1; i < actual_nzmx; i++) | |
5164 | 507 if (sidx[i-1]->r != sidx[i]->r || sidx[i-1]->c != sidx[i]->c) |
5604 | 508 real_nzmx++; |
509 | |
510 rep = new typename Sparse<T>::SparseRep (nr, nc, real_nzmx); | |
5164 | 511 |
5275 | 512 octave_idx_type cx = 0; |
513 octave_idx_type prev_rval = -1; | |
514 octave_idx_type prev_cval = -1; | |
515 octave_idx_type ii = -1; | |
5164 | 516 xcidx (0) = 0; |
5604 | 517 for (octave_idx_type i = 0; i < actual_nzmx; i++) |
5164 | 518 { |
519 OCTAVE_QUIT; | |
5275 | 520 octave_idx_type iidx = sidx[i]->idx; |
521 octave_idx_type rval = sidx[i]->r; | |
522 octave_idx_type cval = sidx[i]->c; | |
5164 | 523 |
524 if (prev_cval < cval || (prev_rval < rval && prev_cval == cval)) | |
525 { | |
5275 | 526 octave_idx_type ci = static_cast<octave_idx_type> (c (ci_scalar ? 0 : iidx)); |
5164 | 527 ii++; |
528 | |
529 while (cx < ci) | |
530 xcidx (++cx) = ii; | |
531 xdata(ii) = a (cf_scalar ? 0 : iidx); | |
5275 | 532 xridx(ii) = static_cast<octave_idx_type> (r (ri_scalar ? 0 : iidx)); |
5164 | 533 } |
534 else | |
535 { | |
536 if (sum_terms) | |
537 xdata(ii) += a (cf_scalar ? 0 : iidx); | |
538 else | |
539 xdata(ii) = a (cf_scalar ? 0 : iidx); | |
540 } | |
541 prev_rval = rval; | |
542 prev_cval = cval; | |
543 } | |
544 | |
545 while (cx < nc) | |
546 xcidx (++cx) = ii + 1; | |
547 } | |
548 } | |
549 } | |
550 | |
551 template <class T> | |
552 Sparse<T>::Sparse (const Array2<T>& a) | |
553 : dimensions (a.dims ()), idx (0), idx_count (0) | |
554 { | |
5275 | 555 octave_idx_type nr = rows (); |
556 octave_idx_type nc = cols (); | |
557 octave_idx_type len = a.length (); | |
5604 | 558 octave_idx_type new_nzmx = 0; |
5164 | 559 |
560 // First count the number of non-zero terms | |
5275 | 561 for (octave_idx_type i = 0; i < len; i++) |
5164 | 562 if (a(i) != T ()) |
5604 | 563 new_nzmx++; |
564 | |
565 rep = new typename Sparse<T>::SparseRep (nr, nc, new_nzmx); | |
5164 | 566 |
5275 | 567 octave_idx_type ii = 0; |
5164 | 568 xcidx(0) = 0; |
5275 | 569 for (octave_idx_type j = 0; j < nc; j++) |
5164 | 570 { |
5275 | 571 for (octave_idx_type i = 0; i < nr; i++) |
5164 | 572 if (a.elem (i,j) != T ()) |
573 { | |
574 xdata(ii) = a.elem (i,j); | |
575 xridx(ii++) = i; | |
576 } | |
577 xcidx(j+1) = ii; | |
578 } | |
579 } | |
580 | |
581 template <class T> | |
582 Sparse<T>::Sparse (const Array<T>& a) | |
583 : dimensions (a.dims ()), idx (0), idx_count (0) | |
584 { | |
585 if (dimensions.length () > 2) | |
586 (*current_liboctave_error_handler) | |
587 ("Sparse::Sparse (const Array<T>&): dimension mismatch"); | |
588 else | |
589 { | |
5275 | 590 octave_idx_type nr = rows (); |
591 octave_idx_type nc = cols (); | |
592 octave_idx_type len = a.length (); | |
5604 | 593 octave_idx_type new_nzmx = 0; |
5164 | 594 |
595 // First count the number of non-zero terms | |
5275 | 596 for (octave_idx_type i = 0; i < len; i++) |
5164 | 597 if (a(i) != T ()) |
5604 | 598 new_nzmx++; |
599 | |
600 rep = new typename Sparse<T>::SparseRep (nr, nc, new_nzmx); | |
5164 | 601 |
5275 | 602 octave_idx_type ii = 0; |
5164 | 603 xcidx(0) = 0; |
5275 | 604 for (octave_idx_type j = 0; j < nc; j++) |
5164 | 605 { |
5275 | 606 for (octave_idx_type i = 0; i < nr; i++) |
5164 | 607 if (a.elem (i,j) != T ()) |
608 { | |
609 xdata(ii) = a.elem (i,j); | |
610 xridx(ii++) = i; | |
611 } | |
612 xcidx(j+1) = ii; | |
613 } | |
614 } | |
615 } | |
616 | |
617 template <class T> | |
618 Sparse<T>::~Sparse (void) | |
619 { | |
620 if (--rep->count <= 0) | |
621 delete rep; | |
622 | |
623 delete [] idx; | |
624 } | |
625 | |
626 template <class T> | |
7717
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
627 Sparse<T>& |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
628 Sparse<T>::operator = (const Sparse<T>& a) |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
629 { |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
630 if (this != &a) |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
631 { |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
632 if (--rep->count <= 0) |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
633 delete rep; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
634 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
635 rep = a.rep; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
636 rep->count++; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
637 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
638 dimensions = a.dimensions; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
639 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
640 delete [] idx; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
641 idx_count = 0; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
642 idx = 0; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
643 } |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
644 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
645 return *this; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
646 } |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
647 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
648 template <class T> |
5275 | 649 octave_idx_type |
650 Sparse<T>::compute_index (const Array<octave_idx_type>& ra_idx) const | |
5164 | 651 { |
5275 | 652 octave_idx_type retval = -1; |
653 | |
654 octave_idx_type n = dimensions.length (); | |
5164 | 655 |
656 if (n > 0 && n == ra_idx.length ()) | |
657 { | |
658 retval = ra_idx(--n); | |
659 | |
660 while (--n >= 0) | |
661 { | |
662 retval *= dimensions(n); | |
663 retval += ra_idx(n); | |
664 } | |
665 } | |
666 else | |
667 (*current_liboctave_error_handler) | |
668 ("Sparse<T>::compute_index: invalid ra_idxing operation"); | |
669 | |
670 return retval; | |
671 } | |
672 | |
673 template <class T> | |
674 T | |
5275 | 675 Sparse<T>::range_error (const char *fcn, octave_idx_type n) const |
5164 | 676 { |
677 (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n); | |
678 return T (); | |
679 } | |
680 | |
681 template <class T> | |
682 T& | |
5275 | 683 Sparse<T>::range_error (const char *fcn, octave_idx_type n) |
5164 | 684 { |
685 (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n); | |
686 static T foo; | |
687 return foo; | |
688 } | |
689 | |
690 template <class T> | |
691 T | |
5275 | 692 Sparse<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const |
5164 | 693 { |
694 (*current_liboctave_error_handler) | |
695 ("%s (%d, %d): range error", fcn, i, j); | |
696 return T (); | |
697 } | |
698 | |
699 template <class T> | |
700 T& | |
5275 | 701 Sparse<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j) |
5164 | 702 { |
703 (*current_liboctave_error_handler) | |
704 ("%s (%d, %d): range error", fcn, i, j); | |
705 static T foo; | |
706 return foo; | |
707 } | |
708 | |
709 template <class T> | |
710 T | |
5275 | 711 Sparse<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const |
5164 | 712 { |
5765 | 713 std::ostringstream buf; |
5164 | 714 |
715 buf << fcn << " ("; | |
716 | |
5275 | 717 octave_idx_type n = ra_idx.length (); |
5164 | 718 |
719 if (n > 0) | |
720 buf << ra_idx(0); | |
721 | |
5275 | 722 for (octave_idx_type i = 1; i < n; i++) |
5164 | 723 buf << ", " << ra_idx(i); |
724 | |
725 buf << "): range error"; | |
5765 | 726 |
727 std::string buf_str = buf.str (); | |
728 | |
729 (*current_liboctave_error_handler) (buf_str.c_str ()); | |
5164 | 730 |
731 return T (); | |
732 } | |
733 | |
734 template <class T> | |
735 T& | |
5275 | 736 Sparse<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) |
5164 | 737 { |
5765 | 738 std::ostringstream buf; |
5164 | 739 |
740 buf << fcn << " ("; | |
741 | |
5275 | 742 octave_idx_type n = ra_idx.length (); |
5164 | 743 |
744 if (n > 0) | |
745 buf << ra_idx(0); | |
746 | |
5275 | 747 for (octave_idx_type i = 1; i < n; i++) |
5164 | 748 buf << ", " << ra_idx(i); |
749 | |
750 buf << "): range error"; | |
751 | |
5765 | 752 std::string buf_str = buf.str (); |
753 | |
754 (*current_liboctave_error_handler) (buf_str.c_str ()); | |
5164 | 755 |
756 static T foo; | |
757 return foo; | |
758 } | |
759 | |
760 template <class T> | |
761 Sparse<T> | |
762 Sparse<T>::reshape (const dim_vector& new_dims) const | |
763 { | |
764 Sparse<T> retval; | |
6689 | 765 dim_vector dims2 = new_dims; |
766 | |
767 if (dims2.length () > 2) | |
5164 | 768 { |
6814 | 769 (*current_liboctave_warning_handler) |
770 ("reshape: sparse reshape to N-d array smashes dims"); | |
771 | |
6689 | 772 for (octave_idx_type i = 2; i < dims2.length(); i++) |
6814 | 773 dims2(1) *= dims2(i); |
774 | |
6689 | 775 dims2.resize (2); |
776 } | |
777 | |
778 if (dimensions != dims2) | |
779 { | |
780 if (dimensions.numel () == dims2.numel ()) | |
5164 | 781 { |
5681 | 782 octave_idx_type new_nnz = nnz (); |
6689 | 783 octave_idx_type new_nr = dims2 (0); |
784 octave_idx_type new_nc = dims2 (1); | |
5275 | 785 octave_idx_type old_nr = rows (); |
786 octave_idx_type old_nc = cols (); | |
5681 | 787 retval = Sparse<T> (new_nr, new_nc, new_nnz); |
5164 | 788 |
5275 | 789 octave_idx_type kk = 0; |
5164 | 790 retval.xcidx(0) = 0; |
5275 | 791 for (octave_idx_type i = 0; i < old_nc; i++) |
792 for (octave_idx_type j = cidx(i); j < cidx(i+1); j++) | |
5164 | 793 { |
5275 | 794 octave_idx_type tmp = i * old_nr + ridx(j); |
795 octave_idx_type ii = tmp % new_nr; | |
796 octave_idx_type jj = (tmp - ii) / new_nr; | |
797 for (octave_idx_type k = kk; k < jj; k++) | |
5164 | 798 retval.xcidx(k+1) = j; |
799 kk = jj; | |
800 retval.xdata(j) = data(j); | |
801 retval.xridx(j) = ii; | |
802 } | |
5275 | 803 for (octave_idx_type k = kk; k < new_nc; k++) |
5681 | 804 retval.xcidx(k+1) = new_nnz; |
5164 | 805 } |
806 else | |
8527
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
807 { |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
808 std::string dimensions_str = dimensions.str (); |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
809 std::string new_dims_str = new_dims.str (); |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
810 |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
811 (*current_liboctave_error_handler) |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
812 ("reshape: can't reshape %s array to %s array", |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
813 dimensions_str.c_str (), new_dims_str.c_str ()); |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
814 } |
5164 | 815 } |
816 else | |
817 retval = *this; | |
818 | |
819 return retval; | |
820 } | |
821 | |
822 template <class T> | |
823 Sparse<T> | |
5275 | 824 Sparse<T>::permute (const Array<octave_idx_type>& perm_vec, bool) const |
5164 | 825 { |
6813 | 826 // The only valid permutations of a sparse array are [1, 2] and [2, 1]. |
827 | |
828 bool fail = false; | |
6817 | 829 bool trans = false; |
6813 | 830 |
831 if (perm_vec.length () == 2) | |
5164 | 832 { |
6813 | 833 if (perm_vec(0) == 0 && perm_vec(1) == 1) |
834 /* do nothing */; | |
835 else if (perm_vec(0) == 1 && perm_vec(1) == 0) | |
6817 | 836 trans = true; |
5164 | 837 else |
6813 | 838 fail = true; |
5164 | 839 } |
840 else | |
6813 | 841 fail = true; |
842 | |
843 if (fail) | |
844 (*current_liboctave_error_handler) | |
845 ("permutation vector contains an invalid element"); | |
846 | |
6817 | 847 return trans ? this->transpose () : *this; |
5164 | 848 } |
849 | |
850 template <class T> | |
851 void | |
852 Sparse<T>::resize_no_fill (const dim_vector& dv) | |
853 { | |
5275 | 854 octave_idx_type n = dv.length (); |
5164 | 855 |
856 if (n != 2) | |
857 { | |
858 (*current_liboctave_error_handler) ("sparse array must be 2-D"); | |
859 return; | |
860 } | |
861 | |
862 resize_no_fill (dv(0), dv(1)); | |
863 } | |
864 | |
865 template <class T> | |
866 void | |
5275 | 867 Sparse<T>::resize_no_fill (octave_idx_type r, octave_idx_type c) |
5164 | 868 { |
869 if (r < 0 || c < 0) | |
870 { | |
871 (*current_liboctave_error_handler) | |
872 ("can't resize to negative dimension"); | |
873 return; | |
874 } | |
875 | |
876 if (ndims () == 0) | |
877 dimensions = dim_vector (0, 0); | |
878 | |
879 if (r == dim1 () && c == dim2 ()) | |
880 return; | |
881 | |
5731 | 882 typename Sparse<T>::SparseRep *old_rep = rep; |
883 | |
5275 | 884 octave_idx_type nc = cols (); |
885 octave_idx_type nr = rows (); | |
5164 | 886 |
5681 | 887 if (nnz () == 0 || r == 0 || c == 0) |
5164 | 888 // Special case of redimensioning to/from a sparse matrix with |
889 // no elements | |
890 rep = new typename Sparse<T>::SparseRep (r, c); | |
891 else | |
892 { | |
5275 | 893 octave_idx_type n = 0; |
5164 | 894 Sparse<T> tmpval; |
895 if (r >= nr) | |
896 { | |
897 if (c > nc) | |
5731 | 898 n = xcidx(nc); |
5164 | 899 else |
5731 | 900 n = xcidx(c); |
5164 | 901 |
902 tmpval = Sparse<T> (r, c, n); | |
903 | |
904 if (c > nc) | |
905 { | |
6101 | 906 for (octave_idx_type i = 0; i < nc + 1; i++) |
5731 | 907 tmpval.cidx(i) = xcidx(i); |
6101 | 908 for (octave_idx_type i = nc + 1; i < c + 1; i++) |
5164 | 909 tmpval.cidx(i) = tmpval.cidx(i-1); |
910 } | |
911 else if (c <= nc) | |
6101 | 912 for (octave_idx_type i = 0; i < c + 1; i++) |
5731 | 913 tmpval.cidx(i) = xcidx(i); |
5164 | 914 |
5275 | 915 for (octave_idx_type i = 0; i < n; i++) |
5164 | 916 { |
5731 | 917 tmpval.data(i) = xdata(i); |
918 tmpval.ridx(i) = xridx(i); | |
5164 | 919 } |
920 } | |
921 else | |
922 { | |
923 // Count how many non zero terms before we do anything | |
6101 | 924 octave_idx_type min_nc = (c < nc ? c : nc); |
925 for (octave_idx_type i = 0; i < min_nc; i++) | |
5731 | 926 for (octave_idx_type j = xcidx(i); j < xcidx(i+1); j++) |
927 if (xridx(j) < r) | |
5164 | 928 n++; |
929 | |
930 if (n) | |
931 { | |
932 // Now that we know the size we can do something | |
933 tmpval = Sparse<T> (r, c, n); | |
934 | |
935 tmpval.cidx(0); | |
6101 | 936 for (octave_idx_type i = 0, ii = 0; i < min_nc; i++) |
5164 | 937 { |
5731 | 938 for (octave_idx_type j = xcidx(i); j < xcidx(i+1); j++) |
939 if (xridx(j) < r) | |
5164 | 940 { |
5731 | 941 tmpval.data(ii) = xdata(j); |
942 tmpval.ridx(ii++) = xridx(j); | |
5164 | 943 } |
944 tmpval.cidx(i+1) = ii; | |
945 } | |
6101 | 946 if (c > min_nc) |
947 for (octave_idx_type i = nc; i < c; i++) | |
948 tmpval.cidx(i+1) = tmpval.cidx(i); | |
5164 | 949 } |
950 else | |
951 tmpval = Sparse<T> (r, c); | |
952 } | |
953 | |
954 rep = tmpval.rep; | |
955 rep->count++; | |
956 } | |
957 | |
958 dimensions = dim_vector (r, c); | |
959 | |
960 if (--old_rep->count <= 0) | |
961 delete old_rep; | |
962 } | |
963 | |
964 template <class T> | |
965 Sparse<T>& | |
5275 | 966 Sparse<T>::insert (const Sparse<T>& a, octave_idx_type r, octave_idx_type c) |
5164 | 967 { |
5275 | 968 octave_idx_type a_rows = a.rows (); |
969 octave_idx_type a_cols = a.cols (); | |
970 octave_idx_type nr = rows (); | |
971 octave_idx_type nc = cols (); | |
5164 | 972 |
973 if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ()) | |
974 { | |
975 (*current_liboctave_error_handler) ("range error for insert"); | |
976 return *this; | |
977 } | |
978 | |
979 // First count the number of elements in the final array | |
5681 | 980 octave_idx_type nel = cidx(c) + a.nnz (); |
5164 | 981 |
982 if (c + a_cols < nc) | |
983 nel += cidx(nc) - cidx(c + a_cols); | |
984 | |
5275 | 985 for (octave_idx_type i = c; i < c + a_cols; i++) |
986 for (octave_idx_type j = cidx(i); j < cidx(i+1); j++) | |
5164 | 987 if (ridx(j) < r || ridx(j) >= r + a_rows) |
988 nel++; | |
989 | |
990 Sparse<T> tmp (*this); | |
991 --rep->count; | |
992 rep = new typename Sparse<T>::SparseRep (nr, nc, nel); | |
993 | |
5275 | 994 for (octave_idx_type i = 0; i < tmp.cidx(c); i++) |
5164 | 995 { |
996 data(i) = tmp.data(i); | |
997 ridx(i) = tmp.ridx(i); | |
998 } | |
5275 | 999 for (octave_idx_type i = 0; i < c + 1; i++) |
5164 | 1000 cidx(i) = tmp.cidx(i); |
1001 | |
5275 | 1002 octave_idx_type ii = cidx(c); |
1003 | |
1004 for (octave_idx_type i = c; i < c + a_cols; i++) | |
5164 | 1005 { |
1006 OCTAVE_QUIT; | |
1007 | |
5275 | 1008 for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++) |
5164 | 1009 if (tmp.ridx(j) < r) |
1010 { | |
1011 data(ii) = tmp.data(j); | |
1012 ridx(ii++) = tmp.ridx(j); | |
1013 } | |
1014 | |
1015 OCTAVE_QUIT; | |
1016 | |
5275 | 1017 for (octave_idx_type j = a.cidx(i-c); j < a.cidx(i-c+1); j++) |
5164 | 1018 { |
1019 data(ii) = a.data(j); | |
1020 ridx(ii++) = r + a.ridx(j); | |
1021 } | |
1022 | |
1023 OCTAVE_QUIT; | |
1024 | |
5275 | 1025 for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++) |
5164 | 1026 if (tmp.ridx(j) >= r + a_rows) |
1027 { | |
1028 data(ii) = tmp.data(j); | |
1029 ridx(ii++) = tmp.ridx(j); | |
1030 } | |
1031 | |
1032 cidx(i+1) = ii; | |
1033 } | |
1034 | |
5275 | 1035 for (octave_idx_type i = c + a_cols; i < nc; i++) |
5164 | 1036 { |
5275 | 1037 for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++) |
5164 | 1038 { |
1039 data(ii) = tmp.data(j); | |
1040 ridx(ii++) = tmp.ridx(j); | |
1041 } | |
1042 cidx(i+1) = ii; | |
1043 } | |
1044 | |
1045 return *this; | |
1046 } | |
1047 | |
1048 template <class T> | |
1049 Sparse<T>& | |
5275 | 1050 Sparse<T>::insert (const Sparse<T>& a, const Array<octave_idx_type>& ra_idx) |
5164 | 1051 { |
1052 | |
1053 if (ra_idx.length () != 2) | |
1054 { | |
1055 (*current_liboctave_error_handler) ("range error for insert"); | |
1056 return *this; | |
1057 } | |
1058 | |
1059 return insert (a, ra_idx (0), ra_idx (1)); | |
1060 } | |
1061 | |
1062 template <class T> | |
1063 Sparse<T> | |
1064 Sparse<T>::transpose (void) const | |
1065 { | |
1066 assert (ndims () == 2); | |
1067 | |
5275 | 1068 octave_idx_type nr = rows (); |
1069 octave_idx_type nc = cols (); | |
5648 | 1070 octave_idx_type nz = nnz (); |
5164 | 1071 Sparse<T> retval (nc, nr, nz); |
1072 | |
5648 | 1073 for (octave_idx_type i = 0; i < nz; i++) |
8987
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1074 retval.xcidx (ridx (i) + 1)++; |
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1075 // retval.xcidx[1:nr] holds the row degrees for rows 0:(nr-1) |
5648 | 1076 nz = 0; |
8987
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1077 for (octave_idx_type i = 1; i <= nr; i++) |
5164 | 1078 { |
8987
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1079 const octave_idx_type tmp = retval.xcidx (i); |
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1080 retval.xcidx (i) = nz; |
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1081 nz += tmp; |
5164 | 1082 } |
8987
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1083 // retval.xcidx[1:nr] holds row entry *start* offsets for rows 0:(nr-1) |
5648 | 1084 |
1085 for (octave_idx_type j = 0; j < nc; j++) | |
1086 for (octave_idx_type k = cidx(j); k < cidx(j+1); k++) | |
1087 { | |
8987
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1088 octave_idx_type q = retval.xcidx (ridx (k) + 1)++; |
5648 | 1089 retval.xridx (q) = j; |
1090 retval.xdata (q) = data (k); | |
1091 } | |
8987
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1092 assert (nnz () == retval.xcidx (nr)); |
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1093 // retval.xcidx[1:nr] holds row entry *end* offsets for rows 0:(nr-1) |
542015fada9e
Eliminate the workspace in sparse transpose.
Jason Riedy <jason@acm.org>
parents:
8920
diff
changeset
|
1094 // and retval.xcidx[0:(nr-1)] holds their row entry *start* offsets |
5164 | 1095 |
1096 return retval; | |
1097 } | |
1098 | |
1099 template <class T> | |
1100 void | |
1101 Sparse<T>::clear_index (void) | |
1102 { | |
1103 delete [] idx; | |
1104 idx = 0; | |
1105 idx_count = 0; | |
1106 } | |
1107 | |
1108 template <class T> | |
1109 void | |
1110 Sparse<T>::set_index (const idx_vector& idx_arg) | |
1111 { | |
5275 | 1112 octave_idx_type nd = ndims (); |
5164 | 1113 |
1114 if (! idx && nd > 0) | |
1115 idx = new idx_vector [nd]; | |
1116 | |
1117 if (idx_count < nd) | |
1118 { | |
1119 idx[idx_count++] = idx_arg; | |
1120 } | |
1121 else | |
1122 { | |
1123 idx_vector *new_idx = new idx_vector [idx_count+1]; | |
1124 | |
5275 | 1125 for (octave_idx_type i = 0; i < idx_count; i++) |
5164 | 1126 new_idx[i] = idx[i]; |
1127 | |
1128 new_idx[idx_count++] = idx_arg; | |
1129 | |
1130 delete [] idx; | |
1131 | |
1132 idx = new_idx; | |
1133 } | |
1134 } | |
1135 | |
1136 template <class T> | |
1137 void | |
1138 Sparse<T>::maybe_delete_elements (idx_vector& idx_arg) | |
1139 { | |
5275 | 1140 octave_idx_type nr = dim1 (); |
1141 octave_idx_type nc = dim2 (); | |
5164 | 1142 |
1143 if (nr == 0 && nc == 0) | |
1144 return; | |
1145 | |
5275 | 1146 octave_idx_type n; |
5164 | 1147 if (nr == 1) |
1148 n = nc; | |
1149 else if (nc == 1) | |
1150 n = nr; | |
1151 else | |
1152 { | |
1153 // Reshape to row vector for Matlab compatibility. | |
1154 | |
1155 n = nr * nc; | |
1156 nr = 1; | |
1157 nc = n; | |
1158 } | |
1159 | |
1160 if (idx_arg.is_colon_equiv (n, 1)) | |
1161 { | |
1162 // Either A(:) = [] or A(idx) = [] with idx enumerating all | |
1163 // elements, so we delete all elements and return [](0x0). To | |
1164 // preserve the orientation of the vector, you have to use | |
1165 // A(idx,:) = [] (delete rows) or A(:,idx) (delete columns). | |
1166 | |
1167 resize_no_fill (0, 0); | |
1168 return; | |
1169 } | |
1170 | |
1171 idx_arg.sort (true); | |
1172 | |
5275 | 1173 octave_idx_type num_to_delete = idx_arg.length (n); |
5164 | 1174 |
1175 if (num_to_delete != 0) | |
1176 { | |
5275 | 1177 octave_idx_type new_n = n; |
5681 | 1178 octave_idx_type new_nnz = nnz (); |
5275 | 1179 |
1180 octave_idx_type iidx = 0; | |
5164 | 1181 |
1182 const Sparse<T> tmp (*this); | |
1183 | |
5275 | 1184 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1185 { |
1186 OCTAVE_QUIT; | |
1187 | |
1188 if (i == idx_arg.elem (iidx)) | |
1189 { | |
1190 iidx++; | |
1191 new_n--; | |
1192 | |
1193 if (tmp.elem (i) != T ()) | |
5681 | 1194 new_nnz--; |
5164 | 1195 |
1196 if (iidx == num_to_delete) | |
1197 break; | |
1198 } | |
1199 } | |
1200 | |
1201 if (new_n > 0) | |
1202 { | |
1203 rep->count--; | |
1204 | |
1205 if (nr == 1) | |
5681 | 1206 rep = new typename Sparse<T>::SparseRep (1, new_n, new_nnz); |
5164 | 1207 else |
5681 | 1208 rep = new typename Sparse<T>::SparseRep (new_n, 1, new_nnz); |
5164 | 1209 |
5275 | 1210 octave_idx_type ii = 0; |
1211 octave_idx_type jj = 0; | |
5164 | 1212 iidx = 0; |
5275 | 1213 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1214 { |
1215 OCTAVE_QUIT; | |
1216 | |
1217 if (iidx < num_to_delete && i == idx_arg.elem (iidx)) | |
1218 iidx++; | |
1219 else | |
1220 { | |
1221 T el = tmp.elem (i); | |
1222 if (el != T ()) | |
1223 { | |
1224 data(ii) = el; | |
1225 ridx(ii++) = jj; | |
1226 } | |
1227 jj++; | |
1228 } | |
1229 } | |
1230 | |
1231 dimensions.resize (2); | |
1232 | |
1233 if (nr == 1) | |
1234 { | |
1235 ii = 0; | |
1236 cidx(0) = 0; | |
5275 | 1237 for (octave_idx_type i = 0; i < new_n; i++) |
5164 | 1238 { |
1239 OCTAVE_QUIT; | |
1240 if (ridx(ii) == i) | |
1241 ridx(ii++) = 0; | |
1242 cidx(i+1) = ii; | |
1243 } | |
1244 | |
1245 dimensions(0) = 1; | |
1246 dimensions(1) = new_n; | |
1247 } | |
1248 else | |
1249 { | |
1250 cidx(0) = 0; | |
5681 | 1251 cidx(1) = new_nnz; |
5164 | 1252 dimensions(0) = new_n; |
1253 dimensions(1) = 1; | |
1254 } | |
1255 } | |
1256 else | |
1257 (*current_liboctave_error_handler) | |
1258 ("A(idx) = []: index out of range"); | |
1259 } | |
1260 } | |
1261 | |
1262 template <class T> | |
1263 void | |
1264 Sparse<T>::maybe_delete_elements (idx_vector& idx_i, idx_vector& idx_j) | |
1265 { | |
1266 assert (ndims () == 2); | |
1267 | |
5275 | 1268 octave_idx_type nr = dim1 (); |
1269 octave_idx_type nc = dim2 (); | |
5164 | 1270 |
1271 if (nr == 0 && nc == 0) | |
1272 return; | |
1273 | |
1274 if (idx_i.is_colon ()) | |
1275 { | |
1276 if (idx_j.is_colon ()) | |
1277 { | |
1278 // A(:,:) -- We are deleting columns and rows, so the result | |
1279 // is [](0x0). | |
1280 | |
1281 resize_no_fill (0, 0); | |
1282 return; | |
1283 } | |
1284 | |
1285 if (idx_j.is_colon_equiv (nc, 1)) | |
1286 { | |
1287 // A(:,j) -- We are deleting columns by enumerating them, | |
1288 // If we enumerate all of them, we should have zero columns | |
1289 // with the same number of rows that we started with. | |
1290 | |
1291 resize_no_fill (nr, 0); | |
1292 return; | |
1293 } | |
1294 } | |
1295 | |
1296 if (idx_j.is_colon () && idx_i.is_colon_equiv (nr, 1)) | |
1297 { | |
1298 // A(i,:) -- We are deleting rows by enumerating them. If we | |
1299 // enumerate all of them, we should have zero rows with the | |
1300 // same number of columns that we started with. | |
1301 | |
1302 resize_no_fill (0, nc); | |
1303 return; | |
1304 } | |
1305 | |
1306 if (idx_i.is_colon_equiv (nr, 1)) | |
1307 { | |
1308 if (idx_j.is_colon_equiv (nc, 1)) | |
1309 resize_no_fill (0, 0); | |
1310 else | |
1311 { | |
1312 idx_j.sort (true); | |
1313 | |
5275 | 1314 octave_idx_type num_to_delete = idx_j.length (nc); |
5164 | 1315 |
1316 if (num_to_delete != 0) | |
1317 { | |
1318 if (nr == 1 && num_to_delete == nc) | |
1319 resize_no_fill (0, 0); | |
1320 else | |
1321 { | |
5275 | 1322 octave_idx_type new_nc = nc; |
5681 | 1323 octave_idx_type new_nnz = nnz (); |
5275 | 1324 |
1325 octave_idx_type iidx = 0; | |
1326 | |
1327 for (octave_idx_type j = 0; j < nc; j++) | |
5164 | 1328 { |
1329 OCTAVE_QUIT; | |
1330 | |
1331 if (j == idx_j.elem (iidx)) | |
1332 { | |
1333 iidx++; | |
1334 new_nc--; | |
1335 | |
5681 | 1336 new_nnz -= cidx(j+1) - cidx(j); |
5164 | 1337 |
1338 if (iidx == num_to_delete) | |
1339 break; | |
1340 } | |
1341 } | |
1342 | |
1343 if (new_nc > 0) | |
1344 { | |
1345 const Sparse<T> tmp (*this); | |
1346 --rep->count; | |
1347 rep = new typename Sparse<T>::SparseRep (nr, new_nc, | |
5681 | 1348 new_nnz); |
5275 | 1349 octave_idx_type ii = 0; |
1350 octave_idx_type jj = 0; | |
5164 | 1351 iidx = 0; |
1352 cidx(0) = 0; | |
5275 | 1353 for (octave_idx_type j = 0; j < nc; j++) |
5164 | 1354 { |
1355 OCTAVE_QUIT; | |
1356 | |
1357 if (iidx < num_to_delete && j == idx_j.elem (iidx)) | |
1358 iidx++; | |
1359 else | |
1360 { | |
5275 | 1361 for (octave_idx_type i = tmp.cidx(j); |
5164 | 1362 i < tmp.cidx(j+1); i++) |
1363 { | |
1364 data(jj) = tmp.data(i); | |
1365 ridx(jj++) = tmp.ridx(i); | |
1366 } | |
1367 cidx(++ii) = jj; | |
1368 } | |
1369 } | |
1370 | |
1371 dimensions.resize (2); | |
1372 dimensions(1) = new_nc; | |
1373 } | |
1374 else | |
1375 (*current_liboctave_error_handler) | |
1376 ("A(idx) = []: index out of range"); | |
1377 } | |
1378 } | |
1379 } | |
1380 } | |
1381 else if (idx_j.is_colon_equiv (nc, 1)) | |
1382 { | |
1383 if (idx_i.is_colon_equiv (nr, 1)) | |
1384 resize_no_fill (0, 0); | |
1385 else | |
1386 { | |
1387 idx_i.sort (true); | |
1388 | |
5275 | 1389 octave_idx_type num_to_delete = idx_i.length (nr); |
5164 | 1390 |
1391 if (num_to_delete != 0) | |
1392 { | |
1393 if (nc == 1 && num_to_delete == nr) | |
1394 resize_no_fill (0, 0); | |
1395 else | |
1396 { | |
5275 | 1397 octave_idx_type new_nr = nr; |
5681 | 1398 octave_idx_type new_nnz = nnz (); |
5275 | 1399 |
1400 octave_idx_type iidx = 0; | |
1401 | |
1402 for (octave_idx_type i = 0; i < nr; i++) | |
5164 | 1403 { |
1404 OCTAVE_QUIT; | |
1405 | |
1406 if (i == idx_i.elem (iidx)) | |
1407 { | |
1408 iidx++; | |
1409 new_nr--; | |
1410 | |
5681 | 1411 for (octave_idx_type j = 0; j < nnz (); j++) |
5164 | 1412 if (ridx(j) == i) |
5681 | 1413 new_nnz--; |
5164 | 1414 |
1415 if (iidx == num_to_delete) | |
1416 break; | |
1417 } | |
1418 } | |
1419 | |
1420 if (new_nr > 0) | |
1421 { | |
1422 const Sparse<T> tmp (*this); | |
1423 --rep->count; | |
1424 rep = new typename Sparse<T>::SparseRep (new_nr, nc, | |
5681 | 1425 new_nnz); |
5164 | 1426 |
5275 | 1427 octave_idx_type jj = 0; |
5164 | 1428 cidx(0) = 0; |
5275 | 1429 for (octave_idx_type i = 0; i < nc; i++) |
5164 | 1430 { |
1431 iidx = 0; | |
5275 | 1432 for (octave_idx_type j = tmp.cidx(i); j < tmp.cidx(i+1); j++) |
5164 | 1433 { |
1434 OCTAVE_QUIT; | |
1435 | |
5275 | 1436 octave_idx_type ri = tmp.ridx(j); |
5164 | 1437 |
1438 while (iidx < num_to_delete && | |
1439 ri > idx_i.elem (iidx)) | |
1440 { | |
1441 iidx++; | |
1442 } | |
1443 | |
1444 if (iidx == num_to_delete || | |
1445 ri != idx_i.elem(iidx)) | |
1446 { | |
1447 data(jj) = tmp.data(j); | |
1448 ridx(jj++) = ri - iidx; | |
1449 } | |
1450 } | |
1451 cidx(i+1) = jj; | |
1452 } | |
1453 | |
1454 dimensions.resize (2); | |
1455 dimensions(0) = new_nr; | |
1456 } | |
1457 else | |
1458 (*current_liboctave_error_handler) | |
1459 ("A(idx) = []: index out of range"); | |
1460 } | |
1461 } | |
1462 } | |
1463 } | |
1464 } | |
1465 | |
1466 template <class T> | |
1467 void | |
1468 Sparse<T>::maybe_delete_elements (Array<idx_vector>& ra_idx) | |
1469 { | |
1470 if (ra_idx.length () == 1) | |
1471 maybe_delete_elements (ra_idx(0)); | |
1472 else if (ra_idx.length () == 2) | |
1473 maybe_delete_elements (ra_idx(0), ra_idx(1)); | |
1474 else | |
1475 (*current_liboctave_error_handler) | |
1476 ("range error for maybe_delete_elements"); | |
1477 } | |
1478 | |
1479 template <class T> | |
1480 Sparse<T> | |
1481 Sparse<T>::value (void) | |
1482 { | |
1483 Sparse<T> retval; | |
1484 | |
1485 int n_idx = index_count (); | |
1486 | |
1487 if (n_idx == 2) | |
1488 { | |
1489 idx_vector *tmp = get_idx (); | |
1490 | |
1491 idx_vector idx_i = tmp[0]; | |
1492 idx_vector idx_j = tmp[1]; | |
1493 | |
1494 retval = index (idx_i, idx_j); | |
1495 } | |
1496 else if (n_idx == 1) | |
1497 { | |
1498 retval = index (idx[0]); | |
1499 } | |
1500 else | |
1501 (*current_liboctave_error_handler) | |
1502 ("Sparse<T>::value: invalid number of indices specified"); | |
1503 | |
1504 clear_index (); | |
1505 | |
1506 return retval; | |
1507 } | |
1508 | |
1509 template <class T> | |
1510 Sparse<T> | |
1511 Sparse<T>::index (idx_vector& idx_arg, int resize_ok) const | |
1512 { | |
1513 Sparse<T> retval; | |
1514 | |
1515 assert (ndims () == 2); | |
1516 | |
5275 | 1517 octave_idx_type nr = dim1 (); |
1518 octave_idx_type nc = dim2 (); | |
5681 | 1519 octave_idx_type nz = nnz (); |
5275 | 1520 |
1521 octave_idx_type orig_len = nr * nc; | |
5164 | 1522 |
1523 dim_vector idx_orig_dims = idx_arg.orig_dimensions (); | |
1524 | |
5275 | 1525 octave_idx_type idx_orig_rows = idx_arg.orig_rows (); |
1526 octave_idx_type idx_orig_columns = idx_arg.orig_columns (); | |
5164 | 1527 |
1528 if (idx_orig_dims.length () > 2) | |
1529 (*current_liboctave_error_handler) | |
1530 ("Sparse<T>::index: Can not index Sparse<T> with an N-D Array"); | |
1531 else if (idx_arg.is_colon ()) | |
1532 { | |
1533 // Fast magic colon processing. | |
1534 retval = Sparse<T> (nr * nc, 1, nz); | |
1535 | |
5275 | 1536 for (octave_idx_type i = 0; i < nc; i++) |
1537 for (octave_idx_type j = cidx(i); j < cidx(i+1); j++) | |
5164 | 1538 { |
1539 OCTAVE_QUIT; | |
1540 retval.xdata(j) = data(j); | |
1541 retval.xridx(j) = ridx(j) + i * nr; | |
1542 } | |
1543 retval.xcidx(0) = 0; | |
1544 retval.xcidx(1) = nz; | |
1545 } | |
1546 else if (nr == 1 && nc == 1) | |
1547 { | |
1548 // You have to be pretty sick to get to this bit of code, | |
1549 // since you have a scalar stored as a sparse matrix, and | |
1550 // then want to make a dense matrix with sparse | |
1551 // representation. Ok, we'll do it, but you deserve what | |
1552 // you get!! | |
5275 | 1553 octave_idx_type n = idx_arg.freeze (length (), "sparse vector", resize_ok); |
5164 | 1554 if (n == 0) |
7573
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
1555 |
7299 | 1556 retval = Sparse<T> (idx_orig_dims); |
5164 | 1557 else if (nz < 1) |
1558 if (n >= idx_orig_dims.numel ()) | |
1559 retval = Sparse<T> (idx_orig_dims); | |
1560 else | |
1561 retval = Sparse<T> (dim_vector (n, 1)); | |
1562 else if (n >= idx_orig_dims.numel ()) | |
1563 { | |
1564 T el = elem (0); | |
5275 | 1565 octave_idx_type new_nr = idx_orig_rows; |
1566 octave_idx_type new_nc = idx_orig_columns; | |
1567 for (octave_idx_type i = 2; i < idx_orig_dims.length (); i++) | |
5164 | 1568 new_nc *= idx_orig_dims (i); |
1569 | |
1570 retval = Sparse<T> (new_nr, new_nc, idx_arg.ones_count ()); | |
1571 | |
5275 | 1572 octave_idx_type ic = 0; |
1573 for (octave_idx_type i = 0; i < n; i++) | |
5164 | 1574 { |
1575 if (i % new_nr == 0) | |
7322 | 1576 retval.xcidx(i / new_nr) = ic; |
5164 | 1577 |
5275 | 1578 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1579 if (ii == 0) |
1580 { | |
1581 OCTAVE_QUIT; | |
1582 retval.xdata(ic) = el; | |
1583 retval.xridx(ic++) = i % new_nr; | |
1584 } | |
1585 } | |
1586 retval.xcidx (new_nc) = ic; | |
1587 } | |
1588 else | |
1589 { | |
1590 T el = elem (0); | |
1591 retval = Sparse<T> (n, 1, nz); | |
1592 | |
5275 | 1593 for (octave_idx_type i = 0; i < nz; i++) |
5164 | 1594 { |
1595 OCTAVE_QUIT; | |
1596 retval.xdata(i) = el; | |
1597 retval.xridx(i) = i; | |
1598 } | |
1599 retval.xcidx(0) = 0; | |
1600 retval.xcidx(1) = n; | |
1601 } | |
1602 } | |
1603 else if (nr == 1 || nc == 1) | |
1604 { | |
1605 // If indexing a vector with a matrix, return value has same | |
1606 // shape as the index. Otherwise, it has same orientation as | |
1607 // indexed object. | |
5275 | 1608 octave_idx_type len = length (); |
1609 octave_idx_type n = idx_arg.freeze (len, "sparse vector", resize_ok); | |
5164 | 1610 |
1611 if (n == 0) | |
1612 if (nr == 1) | |
1613 retval = Sparse<T> (dim_vector (1, 0)); | |
1614 else | |
1615 retval = Sparse<T> (dim_vector (0, 1)); | |
1616 else if (nz < 1) | |
7573
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
1617 if (idx_orig_rows == 1 || idx_orig_columns == 1) |
5164 | 1618 retval = Sparse<T> ((nr == 1 ? 1 : n), (nr == 1 ? n : 1)); |
1619 else | |
1620 retval = Sparse<T> (idx_orig_dims); | |
1621 else | |
1622 { | |
1623 | |
5604 | 1624 octave_idx_type new_nzmx = 0; |
5164 | 1625 if (nr == 1) |
5275 | 1626 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1627 { |
1628 OCTAVE_QUIT; | |
1629 | |
5275 | 1630 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1631 if (ii < len) |
1632 if (cidx(ii) != cidx(ii+1)) | |
5604 | 1633 new_nzmx++; |
5164 | 1634 } |
1635 else | |
5275 | 1636 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1637 { |
5275 | 1638 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1639 if (ii < len) |
5275 | 1640 for (octave_idx_type j = 0; j < nz; j++) |
5164 | 1641 { |
1642 OCTAVE_QUIT; | |
1643 | |
1644 if (ridx(j) == ii) | |
5604 | 1645 new_nzmx++; |
5164 | 1646 if (ridx(j) >= ii) |
1647 break; | |
1648 } | |
1649 } | |
1650 | |
7573
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
1651 if (idx_orig_rows == 1 || idx_orig_columns == 1) |
5164 | 1652 { |
1653 if (nr == 1) | |
1654 { | |
5604 | 1655 retval = Sparse<T> (1, n, new_nzmx); |
5275 | 1656 octave_idx_type jj = 0; |
5164 | 1657 retval.xcidx(0) = 0; |
5275 | 1658 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1659 { |
1660 OCTAVE_QUIT; | |
1661 | |
5275 | 1662 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1663 if (ii < len) |
1664 if (cidx(ii) != cidx(ii+1)) | |
1665 { | |
1666 retval.xdata(jj) = data(cidx(ii)); | |
1667 retval.xridx(jj++) = 0; | |
1668 } | |
1669 retval.xcidx(i+1) = jj; | |
1670 } | |
1671 } | |
1672 else | |
1673 { | |
5604 | 1674 retval = Sparse<T> (n, 1, new_nzmx); |
5164 | 1675 retval.xcidx(0) = 0; |
5604 | 1676 retval.xcidx(1) = new_nzmx; |
5275 | 1677 octave_idx_type jj = 0; |
1678 for (octave_idx_type i = 0; i < n; i++) | |
5164 | 1679 { |
5275 | 1680 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1681 if (ii < len) |
5275 | 1682 for (octave_idx_type j = 0; j < nz; j++) |
5164 | 1683 { |
1684 OCTAVE_QUIT; | |
1685 | |
1686 if (ridx(j) == ii) | |
1687 { | |
1688 retval.xdata(jj) = data(j); | |
1689 retval.xridx(jj++) = i; | |
1690 } | |
1691 if (ridx(j) >= ii) | |
1692 break; | |
1693 } | |
1694 } | |
1695 } | |
1696 } | |
1697 else | |
1698 { | |
5275 | 1699 octave_idx_type new_nr; |
1700 octave_idx_type new_nc; | |
5164 | 1701 if (n >= idx_orig_dims.numel ()) |
1702 { | |
1703 new_nr = idx_orig_rows; | |
1704 new_nc = idx_orig_columns; | |
1705 } | |
1706 else | |
1707 { | |
1708 new_nr = n; | |
1709 new_nc = 1; | |
1710 } | |
1711 | |
5604 | 1712 retval = Sparse<T> (new_nr, new_nc, new_nzmx); |
5164 | 1713 |
1714 if (nr == 1) | |
1715 { | |
5275 | 1716 octave_idx_type jj = 0; |
5164 | 1717 retval.xcidx(0) = 0; |
5275 | 1718 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1719 { |
1720 OCTAVE_QUIT; | |
1721 | |
5275 | 1722 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1723 if (ii < len) |
1724 if (cidx(ii) != cidx(ii+1)) | |
1725 { | |
1726 retval.xdata(jj) = data(cidx(ii)); | |
1727 retval.xridx(jj++) = 0; | |
1728 } | |
1729 retval.xcidx(i/new_nr+1) = jj; | |
1730 } | |
1731 } | |
1732 else | |
1733 { | |
5275 | 1734 octave_idx_type jj = 0; |
5164 | 1735 retval.xcidx(0) = 0; |
5275 | 1736 for (octave_idx_type i = 0; i < n; i++) |
5164 | 1737 { |
5275 | 1738 octave_idx_type ii = idx_arg.elem (i); |
5164 | 1739 if (ii < len) |
5275 | 1740 for (octave_idx_type j = 0; j < nz; j++) |
5164 | 1741 { |
1742 OCTAVE_QUIT; | |
1743 | |
1744 if (ridx(j) == ii) | |
1745 { | |
1746 retval.xdata(jj) = data(j); | |
1747 retval.xridx(jj++) = i; | |
1748 } | |
1749 if (ridx(j) >= ii) | |
1750 break; | |
1751 } | |
1752 retval.xcidx(i/new_nr+1) = jj; | |
1753 } | |
1754 } | |
1755 } | |
1756 } | |
1757 } | |
1758 else | |
1759 { | |
7573
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
1760 (*current_liboctave_warning_with_id_handler) |
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
1761 ("Octave:fortran-indexing", "single index used for sparse matrix"); |
5164 | 1762 |
1763 // This code is only for indexing matrices. The vector | |
1764 // cases are handled above. | |
1765 | |
1766 idx_arg.freeze (nr * nc, "matrix", resize_ok); | |
1767 | |
1768 if (idx_arg) | |
1769 { | |
5275 | 1770 octave_idx_type result_nr = idx_orig_rows; |
1771 octave_idx_type result_nc = idx_orig_columns; | |
5164 | 1772 |
1773 if (nz < 1) | |
7573
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
1774 retval = Sparse<T> (result_nr, result_nc); |
5164 | 1775 else |
1776 { | |
1777 // Count number of non-zero elements | |
5604 | 1778 octave_idx_type new_nzmx = 0; |
5275 | 1779 octave_idx_type kk = 0; |
1780 for (octave_idx_type j = 0; j < result_nc; j++) | |
5164 | 1781 { |
5275 | 1782 for (octave_idx_type i = 0; i < result_nr; i++) |
5164 | 1783 { |
1784 OCTAVE_QUIT; | |
1785 | |
5275 | 1786 octave_idx_type ii = idx_arg.elem (kk++); |
5164 | 1787 if (ii < orig_len) |
1788 { | |
5275 | 1789 octave_idx_type fr = ii % nr; |
1790 octave_idx_type fc = (ii - fr) / nr; | |
1791 for (octave_idx_type k = cidx(fc); k < cidx(fc+1); k++) | |
5164 | 1792 { |
1793 if (ridx(k) == fr) | |
5604 | 1794 new_nzmx++; |
5164 | 1795 if (ridx(k) >= fr) |
1796 break; | |
1797 } | |
1798 } | |
1799 } | |
1800 } | |
1801 | |
5604 | 1802 retval = Sparse<T> (result_nr, result_nc, new_nzmx); |
5164 | 1803 |
1804 kk = 0; | |
5275 | 1805 octave_idx_type jj = 0; |
5164 | 1806 retval.xcidx(0) = 0; |
5275 | 1807 for (octave_idx_type j = 0; j < result_nc; j++) |
5164 | 1808 { |
5275 | 1809 for (octave_idx_type i = 0; i < result_nr; i++) |
5164 | 1810 { |
1811 OCTAVE_QUIT; | |
1812 | |
5275 | 1813 octave_idx_type ii = idx_arg.elem (kk++); |
5164 | 1814 if (ii < orig_len) |
1815 { | |
5275 | 1816 octave_idx_type fr = ii % nr; |
1817 octave_idx_type fc = (ii - fr) / nr; | |
1818 for (octave_idx_type k = cidx(fc); k < cidx(fc+1); k++) | |
5164 | 1819 { |
1820 if (ridx(k) == fr) | |
1821 { | |
1822 retval.xdata(jj) = data(k); | |
1823 retval.xridx(jj++) = i; | |
1824 } | |
1825 if (ridx(k) >= fr) | |
1826 break; | |
1827 } | |
1828 } | |
1829 } | |
1830 retval.xcidx(j+1) = jj; | |
1831 } | |
1832 } | |
1833 // idx_vector::freeze() printed an error message for us. | |
1834 } | |
1835 } | |
1836 | |
1837 return retval; | |
1838 } | |
1839 | |
6988 | 1840 struct |
1841 idx_node | |
1842 { | |
1843 octave_idx_type i; | |
1844 struct idx_node *next; | |
1845 }; | |
1846 | |
5164 | 1847 template <class T> |
1848 Sparse<T> | |
1849 Sparse<T>::index (idx_vector& idx_i, idx_vector& idx_j, int resize_ok) const | |
1850 { | |
1851 Sparse<T> retval; | |
1852 | |
1853 assert (ndims () == 2); | |
1854 | |
5275 | 1855 octave_idx_type nr = dim1 (); |
1856 octave_idx_type nc = dim2 (); | |
1857 | |
1858 octave_idx_type n = idx_i.freeze (nr, "row", resize_ok); | |
1859 octave_idx_type m = idx_j.freeze (nc, "column", resize_ok); | |
5164 | 1860 |
1861 if (idx_i && idx_j) | |
1862 { | |
1863 if (idx_i.orig_empty () || idx_j.orig_empty () || n == 0 || m == 0) | |
1864 { | |
1865 retval.resize_no_fill (n, m); | |
1866 } | |
5681 | 1867 else |
5164 | 1868 { |
5681 | 1869 int idx_i_colon = idx_i.is_colon_equiv (nr); |
1870 int idx_j_colon = idx_j.is_colon_equiv (nc); | |
1871 | |
1872 if (idx_i_colon && idx_j_colon) | |
1873 { | |
1874 retval = *this; | |
1875 } | |
1876 else | |
5164 | 1877 { |
5681 | 1878 // Identify if the indices have any repeated values |
1879 bool permutation = true; | |
1880 | |
1881 OCTAVE_LOCAL_BUFFER (octave_idx_type, itmp, | |
1882 (nr > nc ? nr : nc)); | |
7433 | 1883 octave_sort<octave_idx_type> lsort; |
5681 | 1884 |
1885 if (n > nr || m > nc) | |
1886 permutation = false; | |
1887 | |
1888 if (permutation && ! idx_i_colon) | |
1889 { | |
1890 // Can't use something like | |
1891 // idx_vector tmp_idx = idx_i; | |
1892 // tmp_idx.sort (true); | |
1893 // if (tmp_idx.length(nr) != n) | |
1894 // permutation = false; | |
1895 // here as there is no make_unique function | |
1896 // for idx_vector type. | |
1897 for (octave_idx_type i = 0; i < n; i++) | |
1898 itmp [i] = idx_i.elem (i); | |
7433 | 1899 lsort.sort (itmp, n); |
5681 | 1900 for (octave_idx_type i = 1; i < n; i++) |
1901 if (itmp[i-1] == itmp[i]) | |
1902 { | |
1903 permutation = false; | |
1904 break; | |
1905 } | |
1906 } | |
1907 if (permutation && ! idx_j_colon) | |
1908 { | |
1909 for (octave_idx_type i = 0; i < m; i++) | |
1910 itmp [i] = idx_j.elem (i); | |
7433 | 1911 lsort.sort (itmp, m); |
5681 | 1912 for (octave_idx_type i = 1; i < m; i++) |
1913 if (itmp[i-1] == itmp[i]) | |
1914 { | |
1915 permutation = false; | |
1916 break; | |
1917 } | |
1918 } | |
1919 | |
1920 if (permutation) | |
5164 | 1921 { |
5681 | 1922 // Special case permutation like indexing for speed |
1923 retval = Sparse<T> (n, m, nnz ()); | |
1924 octave_idx_type *ri = retval.xridx (); | |
1925 | |
5766 | 1926 std::vector<T> X (n); |
5681 | 1927 for (octave_idx_type i = 0; i < nr; i++) |
1928 itmp [i] = -1; | |
1929 for (octave_idx_type i = 0; i < n; i++) | |
1930 itmp[idx_i.elem(i)] = i; | |
1931 | |
1932 octave_idx_type kk = 0; | |
1933 retval.xcidx(0) = 0; | |
1934 for (octave_idx_type j = 0; j < m; j++) | |
1935 { | |
1936 octave_idx_type jj = idx_j.elem (j); | |
1937 for (octave_idx_type i = cidx(jj); i < cidx(jj+1); i++) | |
1938 { | |
6988 | 1939 OCTAVE_QUIT; |
1940 | |
5681 | 1941 octave_idx_type ii = itmp [ridx(i)]; |
1942 if (ii >= 0) | |
1943 { | |
1944 X [ii] = data (i); | |
1945 retval.xridx (kk++) = ii; | |
1946 } | |
1947 } | |
7433 | 1948 lsort.sort (ri + retval.xcidx (j), kk - retval.xcidx (j)); |
5681 | 1949 for (octave_idx_type p = retval.xcidx (j); p < kk; p++) |
1950 retval.xdata (p) = X [retval.xridx (p)]; | |
1951 retval.xcidx(j+1) = kk; | |
1952 } | |
1953 retval.maybe_compress (); | |
1954 } | |
1955 else | |
1956 { | |
6988 | 1957 OCTAVE_LOCAL_BUFFER (struct idx_node, nodes, n); |
1958 OCTAVE_LOCAL_BUFFER (octave_idx_type, start_nodes, nr); | |
1959 | |
1960 for (octave_idx_type i = 0; i < nr; i++) | |
1961 start_nodes[i] = -1; | |
1962 | |
1963 for (octave_idx_type i = 0; i < n; i++) | |
1964 { | |
1965 octave_idx_type ii = idx_i.elem (i); | |
1966 nodes[i].i = i; | |
1967 nodes[i].next = 0; | |
1968 | |
1969 octave_idx_type node = start_nodes[ii]; | |
1970 if (node == -1) | |
1971 start_nodes[ii] = i; | |
1972 else | |
1973 { | |
7322 | 1974 while (nodes[node].next) |
1975 node = nodes[node].next->i; | |
1976 nodes[node].next = nodes + i; | |
6988 | 1977 } |
1978 } | |
1979 | |
5681 | 1980 // First count the number of non-zero elements |
1981 octave_idx_type new_nzmx = 0; | |
1982 for (octave_idx_type j = 0; j < m; j++) | |
5164 | 1983 { |
5681 | 1984 octave_idx_type jj = idx_j.elem (j); |
6988 | 1985 |
1986 if (jj < nc) | |
5164 | 1987 { |
6988 | 1988 for (octave_idx_type i = cidx(jj); |
1989 i < cidx(jj+1); i++) | |
5681 | 1990 { |
6988 | 1991 OCTAVE_QUIT; |
1992 | |
1993 octave_idx_type ii = start_nodes [ridx(i)]; | |
1994 | |
1995 if (ii >= 0) | |
5681 | 1996 { |
6988 | 1997 struct idx_node inode = nodes[ii]; |
1998 | |
1999 while (true) | |
2000 { | |
7326 | 2001 if (idx_i.elem (inode.i) < nr) |
6988 | 2002 new_nzmx ++; |
2003 if (inode.next == 0) | |
2004 break; | |
2005 else | |
2006 inode = *inode.next; | |
2007 } | |
5681 | 2008 } |
2009 } | |
5164 | 2010 } |
2011 } | |
5681 | 2012 |
6988 | 2013 std::vector<T> X (n); |
5681 | 2014 retval = Sparse<T> (n, m, new_nzmx); |
6988 | 2015 octave_idx_type *ri = retval.xridx (); |
5681 | 2016 |
2017 octave_idx_type kk = 0; | |
2018 retval.xcidx(0) = 0; | |
2019 for (octave_idx_type j = 0; j < m; j++) | |
2020 { | |
2021 octave_idx_type jj = idx_j.elem (j); | |
6988 | 2022 if (jj < nc) |
5681 | 2023 { |
6988 | 2024 for (octave_idx_type i = cidx(jj); |
2025 i < cidx(jj+1); i++) | |
5681 | 2026 { |
6988 | 2027 OCTAVE_QUIT; |
2028 | |
2029 octave_idx_type ii = start_nodes [ridx(i)]; | |
2030 | |
2031 if (ii >= 0) | |
5681 | 2032 { |
6988 | 2033 struct idx_node inode = nodes[ii]; |
2034 | |
2035 while (true) | |
5681 | 2036 { |
7326 | 2037 if (idx_i.elem (inode.i) < nr) |
6988 | 2038 { |
2039 X [inode.i] = data (i); | |
2040 retval.xridx (kk++) = inode.i; | |
2041 } | |
2042 | |
2043 if (inode.next == 0) | |
2044 break; | |
2045 else | |
2046 inode = *inode.next; | |
5681 | 2047 } |
2048 } | |
2049 } | |
7433 | 2050 lsort.sort (ri + retval.xcidx (j), |
6988 | 2051 kk - retval.xcidx (j)); |
2052 for (octave_idx_type p = retval.xcidx (j); | |
2053 p < kk; p++) | |
2054 retval.xdata (p) = X [retval.xridx (p)]; | |
2055 retval.xcidx(j+1) = kk; | |
5681 | 2056 } |
2057 } | |
5164 | 2058 } |
2059 } | |
2060 } | |
2061 } | |
2062 // idx_vector::freeze() printed an error message for us. | |
2063 | |
2064 return retval; | |
2065 } | |
2066 | |
2067 template <class T> | |
2068 Sparse<T> | |
2069 Sparse<T>::index (Array<idx_vector>& ra_idx, int resize_ok) const | |
2070 { | |
2071 | |
2072 if (ra_idx.length () != 2) | |
2073 { | |
2074 (*current_liboctave_error_handler) ("range error for index"); | |
2075 return *this; | |
2076 } | |
2077 | |
2078 return index (ra_idx (0), ra_idx (1), resize_ok); | |
2079 } | |
2080 | |
7433 | 2081 // Can't use versions of these in Array.cc due to duplication of the |
2082 // instantiations for Array<double and Sparse<double>, etc | |
2083 template <class T> | |
2084 bool | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2085 sparse_ascending_compare (typename ref_param<T>::type a, |
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2086 typename ref_param<T>::type b) |
7433 | 2087 { |
2088 return (a < b); | |
2089 } | |
2090 | |
2091 template <class T> | |
2092 bool | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2093 sparse_descending_compare (typename ref_param<T>::type a, |
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2094 typename ref_param<T>::type b) |
7433 | 2095 { |
2096 return (a > b); | |
2097 } | |
2098 | |
2099 template <class T> | |
2100 Sparse<T> | |
2101 Sparse<T>::sort (octave_idx_type dim, sortmode mode) const | |
2102 { | |
2103 Sparse<T> m = *this; | |
2104 | |
2105 octave_idx_type nr = m.rows (); | |
2106 octave_idx_type nc = m.columns (); | |
2107 | |
2108 if (m.length () < 1) | |
2109 return m; | |
2110 | |
2111 if (dim > 0) | |
2112 { | |
2113 m = m.transpose (); | |
2114 nr = m.rows (); | |
2115 nc = m.columns (); | |
2116 } | |
2117 | |
2118 octave_sort<T> lsort; | |
2119 | |
2120 if (mode == ASCENDING) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2121 lsort.set_compare (sparse_ascending_compare<T>); |
7433 | 2122 else if (mode == DESCENDING) |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2123 lsort.set_compare (sparse_descending_compare<T>); |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
2124 else |
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
2125 abort (); |
7433 | 2126 |
2127 T *v = m.data (); | |
2128 octave_idx_type *mcidx = m.cidx (); | |
2129 octave_idx_type *mridx = m.ridx (); | |
2130 | |
2131 for (octave_idx_type j = 0; j < nc; j++) | |
2132 { | |
2133 octave_idx_type ns = mcidx [j + 1] - mcidx [j]; | |
2134 lsort.sort (v, ns); | |
2135 | |
2136 octave_idx_type i; | |
2137 if (mode == ASCENDING) | |
2138 { | |
2139 for (i = 0; i < ns; i++) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2140 if (sparse_ascending_compare<T> (static_cast<T> (0), v [i])) |
7433 | 2141 break; |
2142 } | |
2143 else | |
2144 { | |
2145 for (i = 0; i < ns; i++) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2146 if (sparse_descending_compare<T> (static_cast<T> (0), v [i])) |
7433 | 2147 break; |
2148 } | |
2149 for (octave_idx_type k = 0; k < i; k++) | |
2150 mridx [k] = k; | |
2151 for (octave_idx_type k = i; k < ns; k++) | |
2152 mridx [k] = k - ns + nr; | |
2153 | |
2154 v += ns; | |
2155 mridx += ns; | |
2156 } | |
2157 | |
2158 if (dim > 0) | |
2159 m = m.transpose (); | |
2160 | |
2161 return m; | |
2162 } | |
2163 | |
2164 template <class T> | |
2165 Sparse<T> | |
2166 Sparse<T>::sort (Array<octave_idx_type> &sidx, octave_idx_type dim, | |
2167 sortmode mode) const | |
2168 { | |
2169 Sparse<T> m = *this; | |
2170 | |
2171 octave_idx_type nr = m.rows (); | |
2172 octave_idx_type nc = m.columns (); | |
2173 | |
2174 if (m.length () < 1) | |
2175 { | |
2176 sidx = Array<octave_idx_type> (dim_vector (nr, nc)); | |
2177 return m; | |
2178 } | |
2179 | |
2180 if (dim > 0) | |
2181 { | |
2182 m = m.transpose (); | |
2183 nr = m.rows (); | |
2184 nc = m.columns (); | |
2185 } | |
2186 | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2187 octave_sort<T> indexed_sort; |
7433 | 2188 |
2189 if (mode == ASCENDING) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2190 indexed_sort.set_compare (sparse_ascending_compare<T>); |
7433 | 2191 else if (mode == DESCENDING) |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2192 indexed_sort.set_compare (sparse_descending_compare<T>); |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
2193 else |
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
2194 abort (); |
7433 | 2195 |
2196 T *v = m.data (); | |
2197 octave_idx_type *mcidx = m.cidx (); | |
2198 octave_idx_type *mridx = m.ridx (); | |
2199 | |
2200 sidx = Array<octave_idx_type> (dim_vector (nr, nc)); | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2201 OCTAVE_LOCAL_BUFFER (octave_idx_type, vi, nr); |
7433 | 2202 |
2203 for (octave_idx_type j = 0; j < nc; j++) | |
2204 { | |
2205 octave_idx_type ns = mcidx [j + 1] - mcidx [j]; | |
2206 octave_idx_type offset = j * nr; | |
2207 | |
2208 if (ns == 0) | |
2209 { | |
2210 for (octave_idx_type k = 0; k < nr; k++) | |
2211 sidx (offset + k) = k; | |
2212 } | |
2213 else | |
2214 { | |
2215 for (octave_idx_type i = 0; i < ns; i++) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2216 vi[i] = mridx[i]; |
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2217 |
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2218 indexed_sort.sort (v, vi, ns); |
7433 | 2219 |
2220 octave_idx_type i; | |
2221 if (mode == ASCENDING) | |
2222 { | |
2223 for (i = 0; i < ns; i++) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2224 if (sparse_ascending_compare<T> (static_cast<T> (0), v[i])) |
7433 | 2225 break; |
2226 } | |
2227 else | |
2228 { | |
2229 for (i = 0; i < ns; i++) | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2230 if (sparse_descending_compare<T> (static_cast<T> (0), v[i])) |
7433 | 2231 break; |
2232 } | |
2233 | |
2234 octave_idx_type ii = 0; | |
2235 octave_idx_type jj = i; | |
2236 for (octave_idx_type k = 0; k < nr; k++) | |
2237 { | |
2238 if (ii < ns && mridx[ii] == k) | |
2239 ii++; | |
2240 else | |
2241 sidx (offset + jj++) = k; | |
2242 } | |
2243 | |
2244 for (octave_idx_type k = 0; k < i; k++) | |
2245 { | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2246 sidx (k + offset) = vi [k]; |
7433 | 2247 mridx [k] = k; |
2248 } | |
2249 | |
2250 for (octave_idx_type k = i; k < ns; k++) | |
2251 { | |
8752
06b9903a029b
fix & clean up complex & sparse sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8677
diff
changeset
|
2252 sidx (k - ns + nr + offset) = vi [k]; |
7433 | 2253 mridx [k] = k - ns + nr; |
2254 } | |
2255 | |
2256 v += ns; | |
2257 mridx += ns; | |
2258 } | |
2259 } | |
2260 | |
2261 if (dim > 0) | |
2262 { | |
2263 m = m.transpose (); | |
2264 sidx = sidx.transpose (); | |
2265 } | |
2266 | |
2267 return m; | |
2268 } | |
2269 | |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2270 template <class T> |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2271 Sparse<T> |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2272 Sparse<T>::diag (octave_idx_type k) const |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2273 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2274 octave_idx_type nnr = rows (); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2275 octave_idx_type nnc = cols (); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2276 Sparse<T> d; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2277 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2278 if (nnr == 0 || nnc == 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2279 ; // do nothing |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2280 else if (nnr != 1 && nnc != 1) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2281 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2282 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2283 nnc -= k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2284 else if (k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2285 nnr += k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2286 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2287 if (nnr > 0 && nnc > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2288 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2289 octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2290 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2291 // Count the number of non-zero elements |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2292 octave_idx_type nel = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2293 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2294 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2295 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2296 if (elem (i, i+k) != 0.) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2297 nel++; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2298 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2299 else if ( k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2300 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2301 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2302 if (elem (i-k, i) != 0.) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2303 nel++; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2304 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2305 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2306 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2307 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2308 if (elem (i, i) != 0.) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2309 nel++; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2310 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2311 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2312 d = Sparse<T> (ndiag, 1, nel); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2313 d.xcidx (0) = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2314 d.xcidx (1) = nel; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2315 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2316 octave_idx_type ii = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2317 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2318 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2319 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2320 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2321 T tmp = elem (i, i+k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2322 if (tmp != 0.) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2323 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2324 d.xdata (ii) = tmp; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2325 d.xridx (ii++) = i; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2326 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2327 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2328 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2329 else if ( k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2330 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2331 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2332 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2333 T tmp = elem (i-k, i); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2334 if (tmp != 0.) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2335 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2336 d.xdata (ii) = tmp; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2337 d.xridx (ii++) = i; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2338 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2339 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2340 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2341 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2342 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2343 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2344 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2345 T tmp = elem (i, i); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2346 if (tmp != 0.) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2347 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2348 d.xdata (ii) = tmp; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2349 d.xridx (ii++) = i; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2350 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2351 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2352 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2353 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2354 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2355 (*current_liboctave_error_handler) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2356 ("diag: requested diagonal out of range"); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2357 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2358 else if (nnr != 0 && nnc != 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2359 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2360 octave_idx_type roff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2361 octave_idx_type coff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2362 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2363 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2364 roff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2365 coff = k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2366 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2367 else if (k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2368 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2369 roff = -k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2370 coff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2371 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2372 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2373 if (nnr == 1) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2374 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2375 octave_idx_type n = nnc + std::abs (k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2376 octave_idx_type nz = nzmax (); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2377 d = Sparse<T> (n, n, nz); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2378 for (octave_idx_type i = 0; i < coff+1; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2379 d.xcidx (i) = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2380 for (octave_idx_type j = 0; j < nnc; j++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2381 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2382 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2383 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2384 d.xdata (i) = data (i); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2385 d.xridx (i) = j + roff; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2386 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2387 d.xcidx (j + coff + 1) = cidx(j+1); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2388 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2389 for (octave_idx_type i = nnc + coff + 1; i < n + 1; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2390 d.xcidx (i) = nz; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2391 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2392 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2393 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2394 octave_idx_type n = nnr + std::abs (k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2395 octave_idx_type nz = nzmax (); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2396 octave_idx_type ii = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2397 octave_idx_type ir = ridx(0); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2398 d = Sparse<T> (n, n, nz); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2399 for (octave_idx_type i = 0; i < coff+1; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2400 d.xcidx (i) = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2401 for (octave_idx_type i = 0; i < nnr; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2402 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2403 if (ir == i) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2404 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2405 d.xdata (ii) = data (ii); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2406 d.xridx (ii++) = ir + roff; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2407 if (ii != nz) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2408 ir = ridx (ii); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2409 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2410 d.xcidx (i + coff + 1) = ii; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2411 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2412 for (octave_idx_type i = nnr + coff + 1; i < n+1; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2413 d.xcidx (i) = nz; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2414 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2415 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2416 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2417 return d; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2418 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7573
diff
changeset
|
2419 |
5775 | 2420 // FIXME |
5164 | 2421 // Unfortunately numel can overflow for very large but very sparse matrices. |
2422 // For now just flag an error when this happens. | |
2423 template <class LT, class RT> | |
2424 int | |
2425 assign1 (Sparse<LT>& lhs, const Sparse<RT>& rhs) | |
2426 { | |
2427 int retval = 1; | |
2428 | |
2429 idx_vector *idx_tmp = lhs.get_idx (); | |
2430 | |
2431 idx_vector lhs_idx = idx_tmp[0]; | |
2432 | |
5275 | 2433 octave_idx_type lhs_len = lhs.numel (); |
2434 octave_idx_type rhs_len = rhs.numel (); | |
5164 | 2435 |
5828 | 2436 uint64_t long_lhs_len = |
2437 static_cast<uint64_t> (lhs.rows ()) * | |
2438 static_cast<uint64_t> (lhs.cols ()); | |
2439 | |
2440 uint64_t long_rhs_len = | |
2441 static_cast<uint64_t> (rhs.rows ()) * | |
2442 static_cast<uint64_t> (rhs.cols ()); | |
2443 | |
2444 if (long_rhs_len != static_cast<uint64_t>(rhs_len) || | |
2445 long_lhs_len != static_cast<uint64_t>(lhs_len)) | |
5164 | 2446 { |
2447 (*current_liboctave_error_handler) | |
2448 ("A(I) = X: Matrix dimensions too large to ensure correct\n", | |
2449 "operation. This is an limitation that should be removed\n", | |
2450 "in the future."); | |
2451 | |
2452 lhs.clear_index (); | |
2453 return 0; | |
2454 } | |
2455 | |
5275 | 2456 octave_idx_type nr = lhs.rows (); |
2457 octave_idx_type nc = lhs.cols (); | |
5681 | 2458 octave_idx_type nz = lhs.nnz (); |
5275 | 2459 |
5781 | 2460 octave_idx_type n = lhs_idx.freeze (lhs_len, "vector", true); |
5164 | 2461 |
2462 if (n != 0) | |
2463 { | |
5275 | 2464 octave_idx_type max_idx = lhs_idx.max () + 1; |
5164 | 2465 max_idx = max_idx < lhs_len ? lhs_len : max_idx; |
2466 | |
2467 // Take a constant copy of lhs. This means that elem won't | |
2468 // create missing elements. | |
2469 const Sparse<LT> c_lhs (lhs); | |
2470 | |
2471 if (rhs_len == n) | |
2472 { | |
5681 | 2473 octave_idx_type new_nzmx = lhs.nnz (); |
5164 | 2474 |
5603 | 2475 OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx, n); |
2476 if (! lhs_idx.is_colon ()) | |
2477 { | |
2478 // Ok here we have to be careful with the indexing, | |
2479 // to treat cases like "a([3,2,1]) = b", and still | |
2480 // handle the need for strict sorting of the sparse | |
2481 // elements. | |
2482 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *, sidx, n); | |
2483 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort, sidxX, n); | |
2484 | |
2485 for (octave_idx_type i = 0; i < n; i++) | |
2486 { | |
2487 sidx[i] = &sidxX[i]; | |
2488 sidx[i]->i = lhs_idx.elem(i); | |
2489 sidx[i]->idx = i; | |
2490 } | |
2491 | |
2492 OCTAVE_QUIT; | |
2493 octave_sort<octave_idx_vector_sort *> | |
2494 sort (octave_idx_vector_comp); | |
2495 | |
2496 sort.sort (sidx, n); | |
2497 | |
2498 intNDArray<octave_idx_type> new_idx (dim_vector (n,1)); | |
2499 | |
2500 for (octave_idx_type i = 0; i < n; i++) | |
2501 { | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8150
diff
changeset
|
2502 new_idx.xelem(i) = sidx[i]->i; |
5603 | 2503 rhs_idx[i] = sidx[i]->idx; |
2504 } | |
2505 | |
2506 lhs_idx = idx_vector (new_idx); | |
2507 } | |
2508 else | |
2509 for (octave_idx_type i = 0; i < n; i++) | |
2510 rhs_idx[i] = i; | |
2511 | |
5164 | 2512 // First count the number of non-zero elements |
5275 | 2513 for (octave_idx_type i = 0; i < n; i++) |
5164 | 2514 { |
2515 OCTAVE_QUIT; | |
2516 | |
5275 | 2517 octave_idx_type ii = lhs_idx.elem (i); |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2518 if (i < n - 1 && lhs_idx.elem (i + 1) == ii) |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2519 continue; |
5164 | 2520 if (ii < lhs_len && c_lhs.elem(ii) != LT ()) |
5604 | 2521 new_nzmx--; |
5603 | 2522 if (rhs.elem(rhs_idx[i]) != RT ()) |
5604 | 2523 new_nzmx++; |
5164 | 2524 } |
2525 | |
2526 if (nr > 1) | |
2527 { | |
7246 | 2528 Sparse<LT> tmp ((max_idx > nr ? max_idx : nr), 1, new_nzmx); |
5164 | 2529 tmp.cidx(0) = 0; |
5681 | 2530 tmp.cidx(1) = new_nzmx; |
5164 | 2531 |
5275 | 2532 octave_idx_type i = 0; |
2533 octave_idx_type ii = 0; | |
5164 | 2534 if (i < nz) |
2535 ii = c_lhs.ridx(i); | |
2536 | |
5275 | 2537 octave_idx_type j = 0; |
2538 octave_idx_type jj = lhs_idx.elem(j); | |
2539 | |
2540 octave_idx_type kk = 0; | |
5164 | 2541 |
2542 while (j < n || i < nz) | |
2543 { | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2544 if (j < n - 1 && lhs_idx.elem (j + 1) == jj) |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2545 { |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2546 j++; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2547 jj = lhs_idx.elem (j); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2548 continue; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2549 } |
5164 | 2550 if (j == n || (i < nz && ii < jj)) |
2551 { | |
2552 tmp.xdata (kk) = c_lhs.data (i); | |
2553 tmp.xridx (kk++) = ii; | |
2554 if (++i < nz) | |
2555 ii = c_lhs.ridx(i); | |
2556 } | |
2557 else | |
2558 { | |
5603 | 2559 RT rtmp = rhs.elem (rhs_idx[j]); |
5164 | 2560 if (rtmp != RT ()) |
2561 { | |
2562 tmp.xdata (kk) = rtmp; | |
2563 tmp.xridx (kk++) = jj; | |
2564 } | |
2565 | |
2566 if (ii == jj && i < nz) | |
2567 if (++i < nz) | |
2568 ii = c_lhs.ridx(i); | |
2569 if (++j < n) | |
2570 jj = lhs_idx.elem(j); | |
2571 } | |
2572 } | |
2573 | |
2574 lhs = tmp; | |
2575 } | |
2576 else | |
2577 { | |
7246 | 2578 Sparse<LT> tmp (1, (max_idx > nc ? max_idx : nc), new_nzmx); |
5164 | 2579 |
5275 | 2580 octave_idx_type i = 0; |
2581 octave_idx_type ii = 0; | |
5164 | 2582 while (ii < nc && c_lhs.cidx(ii+1) <= i) |
2583 ii++; | |
2584 | |
5275 | 2585 octave_idx_type j = 0; |
2586 octave_idx_type jj = lhs_idx.elem(j); | |
2587 | |
2588 octave_idx_type kk = 0; | |
2589 octave_idx_type ic = 0; | |
5164 | 2590 |
2591 while (j < n || i < nz) | |
2592 { | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2593 if (j < n - 1 && lhs_idx.elem (j + 1) == jj) |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2594 { |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2595 j++; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2596 jj = lhs_idx.elem (j); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2597 continue; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2598 } |
5164 | 2599 if (j == n || (i < nz && ii < jj)) |
2600 { | |
2601 while (ic <= ii) | |
2602 tmp.xcidx (ic++) = kk; | |
2603 tmp.xdata (kk) = c_lhs.data (i); | |
5603 | 2604 tmp.xridx (kk++) = 0; |
5164 | 2605 i++; |
2606 while (ii < nc && c_lhs.cidx(ii+1) <= i) | |
2607 ii++; | |
2608 } | |
2609 else | |
2610 { | |
2611 while (ic <= jj) | |
2612 tmp.xcidx (ic++) = kk; | |
2613 | |
5603 | 2614 RT rtmp = rhs.elem (rhs_idx[j]); |
5164 | 2615 if (rtmp != RT ()) |
5603 | 2616 { |
2617 tmp.xdata (kk) = rtmp; | |
2618 tmp.xridx (kk++) = 0; | |
2619 } | |
5164 | 2620 if (ii == jj) |
2621 { | |
2622 i++; | |
2623 while (ii < nc && c_lhs.cidx(ii+1) <= i) | |
2624 ii++; | |
2625 } | |
2626 j++; | |
2627 if (j < n) | |
2628 jj = lhs_idx.elem(j); | |
2629 } | |
2630 } | |
2631 | |
5275 | 2632 for (octave_idx_type iidx = ic; iidx < max_idx+1; iidx++) |
5164 | 2633 tmp.xcidx(iidx) = kk; |
2634 | |
2635 lhs = tmp; | |
2636 } | |
2637 } | |
2638 else if (rhs_len == 1) | |
2639 { | |
5681 | 2640 octave_idx_type new_nzmx = lhs.nnz (); |
5164 | 2641 RT scalar = rhs.elem (0); |
2642 bool scalar_non_zero = (scalar != RT ()); | |
5603 | 2643 lhs_idx.sort (true); |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
2644 n = lhs_idx.length (n); |
5164 | 2645 |
2646 // First count the number of non-zero elements | |
2647 if (scalar != RT ()) | |
5604 | 2648 new_nzmx += n; |
5275 | 2649 for (octave_idx_type i = 0; i < n; i++) |
5164 | 2650 { |
2651 OCTAVE_QUIT; | |
2652 | |
5275 | 2653 octave_idx_type ii = lhs_idx.elem (i); |
5164 | 2654 if (ii < lhs_len && c_lhs.elem(ii) != LT ()) |
5604 | 2655 new_nzmx--; |
5164 | 2656 } |
2657 | |
2658 if (nr > 1) | |
2659 { | |
7246 | 2660 Sparse<LT> tmp ((max_idx > nr ? max_idx : nr), 1, new_nzmx); |
5164 | 2661 tmp.cidx(0) = 0; |
5681 | 2662 tmp.cidx(1) = new_nzmx; |
5164 | 2663 |
5275 | 2664 octave_idx_type i = 0; |
2665 octave_idx_type ii = 0; | |
5164 | 2666 if (i < nz) |
2667 ii = c_lhs.ridx(i); | |
2668 | |
5275 | 2669 octave_idx_type j = 0; |
2670 octave_idx_type jj = lhs_idx.elem(j); | |
2671 | |
2672 octave_idx_type kk = 0; | |
5164 | 2673 |
2674 while (j < n || i < nz) | |
2675 { | |
2676 if (j == n || (i < nz && ii < jj)) | |
2677 { | |
2678 tmp.xdata (kk) = c_lhs.data (i); | |
2679 tmp.xridx (kk++) = ii; | |
2680 if (++i < nz) | |
2681 ii = c_lhs.ridx(i); | |
2682 } | |
2683 else | |
2684 { | |
2685 if (scalar_non_zero) | |
2686 { | |
2687 tmp.xdata (kk) = scalar; | |
2688 tmp.xridx (kk++) = jj; | |
2689 } | |
2690 | |
2691 if (ii == jj && i < nz) | |
2692 if (++i < nz) | |
2693 ii = c_lhs.ridx(i); | |
2694 if (++j < n) | |
2695 jj = lhs_idx.elem(j); | |
2696 } | |
2697 } | |
2698 | |
2699 lhs = tmp; | |
2700 } | |
2701 else | |
2702 { | |
7246 | 2703 Sparse<LT> tmp (1, (max_idx > nc ? max_idx : nc), new_nzmx); |
5164 | 2704 |
5275 | 2705 octave_idx_type i = 0; |
2706 octave_idx_type ii = 0; | |
5164 | 2707 while (ii < nc && c_lhs.cidx(ii+1) <= i) |
2708 ii++; | |
2709 | |
5275 | 2710 octave_idx_type j = 0; |
2711 octave_idx_type jj = lhs_idx.elem(j); | |
2712 | |
2713 octave_idx_type kk = 0; | |
2714 octave_idx_type ic = 0; | |
5164 | 2715 |
2716 while (j < n || i < nz) | |
2717 { | |
2718 if (j == n || (i < nz && ii < jj)) | |
2719 { | |
2720 while (ic <= ii) | |
2721 tmp.xcidx (ic++) = kk; | |
2722 tmp.xdata (kk) = c_lhs.data (i); | |
2723 i++; | |
2724 while (ii < nc && c_lhs.cidx(ii+1) <= i) | |
2725 ii++; | |
9177
39be2c4531c8
fix sparse indexing bug
Jaroslav Hajek <highegg@gmail.com>
parents:
8987
diff
changeset
|
2726 tmp.xridx (kk++) = 0; |
5164 | 2727 } |
2728 else | |
2729 { | |
2730 while (ic <= jj) | |
2731 tmp.xcidx (ic++) = kk; | |
2732 if (scalar_non_zero) | |
9177
39be2c4531c8
fix sparse indexing bug
Jaroslav Hajek <highegg@gmail.com>
parents:
8987
diff
changeset
|
2733 { |
39be2c4531c8
fix sparse indexing bug
Jaroslav Hajek <highegg@gmail.com>
parents:
8987
diff
changeset
|
2734 tmp.xdata (kk) = scalar; |
39be2c4531c8
fix sparse indexing bug
Jaroslav Hajek <highegg@gmail.com>
parents:
8987
diff
changeset
|
2735 tmp.xridx (kk++) = 0; |
39be2c4531c8
fix sparse indexing bug
Jaroslav Hajek <highegg@gmail.com>
parents:
8987
diff
changeset
|
2736 } |
5164 | 2737 if (ii == jj) |
2738 { | |
2739 i++; | |
2740 while (ii < nc && c_lhs.cidx(ii+1) <= i) | |
2741 ii++; | |
2742 } | |
2743 j++; | |
2744 if (j < n) | |
2745 jj = lhs_idx.elem(j); | |
2746 } | |
2747 } | |
2748 | |
5275 | 2749 for (octave_idx_type iidx = ic; iidx < max_idx+1; iidx++) |
5164 | 2750 tmp.xcidx(iidx) = kk; |
2751 | |
2752 lhs = tmp; | |
2753 } | |
2754 } | |
2755 else | |
2756 { | |
2757 (*current_liboctave_error_handler) | |
2758 ("A(I) = X: X must be a scalar or a vector with same length as I"); | |
2759 | |
2760 retval = 0; | |
2761 } | |
2762 } | |
2763 else if (lhs_idx.is_colon ()) | |
2764 { | |
2765 if (lhs_len == 0) | |
2766 { | |
2767 | |
5681 | 2768 octave_idx_type new_nzmx = rhs.nnz (); |
5604 | 2769 Sparse<LT> tmp (1, rhs_len, new_nzmx); |
5164 | 2770 |
5275 | 2771 octave_idx_type ii = 0; |
2772 octave_idx_type jj = 0; | |
2773 for (octave_idx_type i = 0; i < rhs.cols(); i++) | |
2774 for (octave_idx_type j = rhs.cidx(i); j < rhs.cidx(i+1); j++) | |
5164 | 2775 { |
2776 OCTAVE_QUIT; | |
5275 | 2777 for (octave_idx_type k = jj; k <= i * rhs.rows() + rhs.ridx(j); k++) |
5164 | 2778 tmp.cidx(jj++) = ii; |
2779 | |
2780 tmp.data(ii) = rhs.data(j); | |
2781 tmp.ridx(ii++) = 0; | |
2782 } | |
2783 | |
5275 | 2784 for (octave_idx_type i = jj; i < rhs_len + 1; i++) |
5164 | 2785 tmp.cidx(i) = ii; |
2786 | |
2787 lhs = tmp; | |
2788 } | |
2789 else | |
2790 (*current_liboctave_error_handler) | |
2791 ("A(:) = X: A must be the same size as X"); | |
2792 } | |
2793 else if (! (rhs_len == 1 || rhs_len == 0)) | |
2794 { | |
2795 (*current_liboctave_error_handler) | |
2796 ("A([]) = X: X must also be an empty matrix or a scalar"); | |
2797 | |
2798 retval = 0; | |
2799 } | |
2800 | |
2801 lhs.clear_index (); | |
2802 | |
2803 return retval; | |
2804 } | |
2805 | |
2806 template <class LT, class RT> | |
2807 int | |
2808 assign (Sparse<LT>& lhs, const Sparse<RT>& rhs) | |
2809 { | |
2810 int retval = 1; | |
2811 | |
2812 int n_idx = lhs.index_count (); | |
2813 | |
5275 | 2814 octave_idx_type lhs_nr = lhs.rows (); |
2815 octave_idx_type lhs_nc = lhs.cols (); | |
5681 | 2816 octave_idx_type lhs_nz = lhs.nnz (); |
5275 | 2817 |
2818 octave_idx_type rhs_nr = rhs.rows (); | |
2819 octave_idx_type rhs_nc = rhs.cols (); | |
5164 | 2820 |
2821 idx_vector *tmp = lhs.get_idx (); | |
2822 | |
2823 idx_vector idx_i; | |
2824 idx_vector idx_j; | |
2825 | |
2826 if (n_idx > 2) | |
2827 { | |
2828 (*current_liboctave_error_handler) | |
2829 ("A(I, J) = X: can only have 1 or 2 indexes for sparse matrices"); | |
6092 | 2830 |
2831 lhs.clear_index (); | |
5164 | 2832 return 0; |
2833 } | |
2834 | |
2835 if (n_idx > 1) | |
2836 idx_j = tmp[1]; | |
2837 | |
2838 if (n_idx > 0) | |
2839 idx_i = tmp[0]; | |
2840 | |
6988 | 2841 // Take a constant copy of lhs. This means that ridx and family won't |
2842 // call make_unique. | |
2843 const Sparse<LT> c_lhs (lhs); | |
2844 | |
5164 | 2845 if (n_idx == 2) |
2846 { | |
5781 | 2847 octave_idx_type n = idx_i.freeze (lhs_nr, "row", true); |
2848 octave_idx_type m = idx_j.freeze (lhs_nc, "column", true); | |
5164 | 2849 |
2850 int idx_i_is_colon = idx_i.is_colon (); | |
2851 int idx_j_is_colon = idx_j.is_colon (); | |
2852 | |
7238 | 2853 if (lhs_nr == 0 && lhs_nc == 0) |
2854 { | |
2855 if (idx_i_is_colon) | |
2856 n = rhs_nr; | |
2857 | |
2858 if (idx_j_is_colon) | |
2859 m = rhs_nc; | |
2860 } | |
5164 | 2861 |
2862 if (idx_i && idx_j) | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2863 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2864 if (rhs_nr == 1 && rhs_nc == 1 && n >= 0 && m >= 0) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2865 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2866 if (n > 0 && m > 0) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2867 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2868 idx_i.sort (true); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2869 n = idx_i.length (n); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2870 idx_j.sort (true); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2871 m = idx_j.length (m); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2872 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2873 octave_idx_type max_row_idx = idx_i_is_colon ? rhs_nr : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2874 idx_i.max () + 1; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2875 octave_idx_type max_col_idx = idx_j_is_colon ? rhs_nc : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2876 idx_j.max () + 1; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2877 octave_idx_type new_nr = max_row_idx > lhs_nr ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2878 max_row_idx : lhs_nr; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2879 octave_idx_type new_nc = max_col_idx > lhs_nc ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2880 max_col_idx : lhs_nc; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2881 RT scalar = rhs.elem (0, 0); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2882 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2883 // Count the number of non-zero terms |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2884 octave_idx_type new_nzmx = lhs.nnz (); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2885 for (octave_idx_type j = 0; j < m; j++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2886 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2887 octave_idx_type jj = idx_j.elem (j); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2888 if (jj < lhs_nc) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2889 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2890 for (octave_idx_type i = 0; i < n; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2891 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2892 OCTAVE_QUIT; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2893 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2894 octave_idx_type ii = idx_i.elem (i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2895 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2896 if (ii < lhs_nr) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2897 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2898 for (octave_idx_type k = c_lhs.cidx(jj); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2899 k < c_lhs.cidx(jj+1); k++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2900 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2901 if (c_lhs.ridx(k) == ii) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2902 new_nzmx--; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2903 if (c_lhs.ridx(k) >= ii) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2904 break; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2905 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2906 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2907 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2908 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2909 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2910 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2911 if (scalar != RT()) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2912 new_nzmx += m * n; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2913 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2914 Sparse<LT> stmp (new_nr, new_nc, new_nzmx); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2915 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2916 octave_idx_type jji = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2917 octave_idx_type jj = idx_j.elem (jji); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2918 octave_idx_type kk = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2919 stmp.cidx(0) = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2920 for (octave_idx_type j = 0; j < new_nc; j++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2921 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2922 if (jji < m && jj == j) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2923 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2924 octave_idx_type iii = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2925 octave_idx_type ii = idx_i.elem (iii); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2926 octave_idx_type ppp = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2927 octave_idx_type ppi = (j >= lhs_nc ? 0 : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2928 c_lhs.cidx(j+1) - |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2929 c_lhs.cidx(j)); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2930 octave_idx_type pp = (ppp < ppi ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2931 c_lhs.ridx(c_lhs.cidx(j)+ppp) : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2932 new_nr); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2933 while (ppp < ppi || iii < n) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2934 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2935 if (iii < n && ii <= pp) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2936 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2937 if (scalar != RT ()) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2938 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2939 stmp.data(kk) = scalar; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2940 stmp.ridx(kk++) = ii; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2941 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2942 if (ii == pp) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2943 pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2944 if (++iii < n) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2945 ii = idx_i.elem(iii); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2946 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2947 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2948 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2949 stmp.data(kk) = |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2950 c_lhs.data(c_lhs.cidx(j)+ppp); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2951 stmp.ridx(kk++) = pp; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2952 pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2953 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2954 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2955 if (++jji < m) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2956 jj = idx_j.elem(jji); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2957 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2958 else if (j < lhs_nc) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2959 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2960 for (octave_idx_type i = c_lhs.cidx(j); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2961 i < c_lhs.cidx(j+1); i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2962 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2963 stmp.data(kk) = c_lhs.data(i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2964 stmp.ridx(kk++) = c_lhs.ridx(i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2965 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2966 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2967 stmp.cidx(j+1) = kk; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2968 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2969 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2970 lhs = stmp; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2971 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2972 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2973 { |
7253 | 2974 #if 0 |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2975 // FIXME -- the following code will make this |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2976 // function behave the same as the full matrix |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2977 // case for things like |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2978 // |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2979 // x = sparse (ones (2)); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2980 // x([],3) = 2; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2981 // |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2982 // x = |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2983 // |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2984 // Compressed Column Sparse (rows = 2, cols = 3, nnz = 4) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2985 // |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2986 // (1, 1) -> 1 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2987 // (2, 1) -> 1 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2988 // (1, 2) -> 1 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2989 // (2, 2) -> 1 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2990 // |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2991 // However, Matlab doesn't resize in this case |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2992 // even though it does in the full matrix case. |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2993 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2994 if (n > 0) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2995 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2996 octave_idx_type max_row_idx = idx_i_is_colon ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2997 rhs_nr : idx_i.max () + 1; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2998 octave_idx_type new_nr = max_row_idx > lhs_nr ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
2999 max_row_idx : lhs_nr; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3000 octave_idx_type new_nc = lhs_nc; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3001 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3002 lhs.resize (new_nr, new_nc); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3003 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3004 else if (m > 0) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3005 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3006 octave_idx_type max_col_idx = idx_j_is_colon ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3007 rhs_nc : idx_j.max () + 1; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3008 octave_idx_type new_nr = lhs_nr; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3009 octave_idx_type new_nc = max_col_idx > lhs_nc ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3010 max_col_idx : lhs_nc; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3011 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3012 lhs.resize (new_nr, new_nc); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3013 } |
7253 | 3014 #endif |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3015 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3016 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3017 else if (n == rhs_nr && m == rhs_nc) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3018 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3019 if (n > 0 && m > 0) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3020 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3021 octave_idx_type max_row_idx = idx_i_is_colon ? rhs_nr : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3022 idx_i.max () + 1; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3023 octave_idx_type max_col_idx = idx_j_is_colon ? rhs_nc : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3024 idx_j.max () + 1; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3025 octave_idx_type new_nr = max_row_idx > lhs_nr ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3026 max_row_idx : lhs_nr; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3027 octave_idx_type new_nc = max_col_idx > lhs_nc ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3028 max_col_idx : lhs_nc; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3029 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3030 OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx_i, n); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3031 if (! idx_i.is_colon ()) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3032 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3033 // Ok here we have to be careful with the indexing, |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3034 // to treat cases like "a([3,2,1],:) = b", and still |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3035 // handle the need for strict sorting of the sparse |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3036 // elements. |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3037 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *, |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3038 sidx, n); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3039 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort, |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3040 sidxX, n); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3041 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3042 for (octave_idx_type i = 0; i < n; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3043 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3044 sidx[i] = &sidxX[i]; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3045 sidx[i]->i = idx_i.elem(i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3046 sidx[i]->idx = i; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3047 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3048 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3049 OCTAVE_QUIT; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3050 octave_sort<octave_idx_vector_sort *> |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3051 sort (octave_idx_vector_comp); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3052 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3053 sort.sort (sidx, n); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3054 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3055 intNDArray<octave_idx_type> new_idx (dim_vector (n,1)); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3056 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3057 for (octave_idx_type i = 0; i < n; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3058 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8150
diff
changeset
|
3059 new_idx.xelem(i) = sidx[i]->i; |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3060 rhs_idx_i[i] = sidx[i]->idx; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3061 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3062 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3063 idx_i = idx_vector (new_idx); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3064 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3065 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3066 for (octave_idx_type i = 0; i < n; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3067 rhs_idx_i[i] = i; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3068 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3069 OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx_j, m); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3070 if (! idx_j.is_colon ()) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3071 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3072 // Ok here we have to be careful with the indexing, |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3073 // to treat cases like "a([3,2,1],:) = b", and still |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3074 // handle the need for strict sorting of the sparse |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3075 // elements. |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3076 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *, |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3077 sidx, m); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3078 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort, |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3079 sidxX, m); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3080 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3081 for (octave_idx_type i = 0; i < m; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3082 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3083 sidx[i] = &sidxX[i]; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3084 sidx[i]->i = idx_j.elem(i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3085 sidx[i]->idx = i; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3086 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3087 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3088 OCTAVE_QUIT; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3089 octave_sort<octave_idx_vector_sort *> |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3090 sort (octave_idx_vector_comp); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3091 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3092 sort.sort (sidx, m); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3093 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3094 intNDArray<octave_idx_type> new_idx (dim_vector (m,1)); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3095 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3096 for (octave_idx_type i = 0; i < m; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3097 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8150
diff
changeset
|
3098 new_idx.xelem(i) = sidx[i]->i; |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3099 rhs_idx_j[i] = sidx[i]->idx; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3100 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3101 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3102 idx_j = idx_vector (new_idx); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3103 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3104 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3105 for (octave_idx_type i = 0; i < m; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3106 rhs_idx_j[i] = i; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3107 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3108 // Maximum number of non-zero elements |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3109 octave_idx_type new_nzmx = lhs.nnz() + rhs.nnz(); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3110 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3111 Sparse<LT> stmp (new_nr, new_nc, new_nzmx); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3112 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3113 octave_idx_type jji = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3114 octave_idx_type jj = idx_j.elem (jji); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3115 octave_idx_type kk = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3116 stmp.cidx(0) = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3117 for (octave_idx_type j = 0; j < new_nc; j++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3118 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3119 if (jji < m && jj == j) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3120 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3121 octave_idx_type iii = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3122 octave_idx_type ii = idx_i.elem (iii); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3123 octave_idx_type ppp = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3124 octave_idx_type ppi = (j >= lhs_nc ? 0 : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3125 c_lhs.cidx(j+1) - |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3126 c_lhs.cidx(j)); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3127 octave_idx_type pp = (ppp < ppi ? |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3128 c_lhs.ridx(c_lhs.cidx(j)+ppp) : |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3129 new_nr); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3130 while (ppp < ppi || iii < n) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3131 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3132 if (iii < n && ii <= pp) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3133 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3134 if (iii < n - 1 && |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3135 idx_i.elem (iii + 1) == ii) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3136 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3137 iii++; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3138 ii = idx_i.elem(iii); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3139 continue; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3140 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3141 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3142 RT rtmp = rhs.elem (rhs_idx_i[iii], |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3143 rhs_idx_j[jji]); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3144 if (rtmp != RT ()) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3145 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3146 stmp.data(kk) = rtmp; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3147 stmp.ridx(kk++) = ii; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3148 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3149 if (ii == pp) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3150 pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3151 if (++iii < n) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3152 ii = idx_i.elem(iii); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3153 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3154 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3155 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3156 stmp.data(kk) = |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3157 c_lhs.data(c_lhs.cidx(j)+ppp); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3158 stmp.ridx(kk++) = pp; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3159 pp = (++ppp < ppi ? c_lhs.ridx(c_lhs.cidx(j)+ppp) : new_nr); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3160 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3161 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3162 if (++jji < m) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3163 jj = idx_j.elem(jji); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3164 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3165 else if (j < lhs_nc) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3166 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3167 for (octave_idx_type i = c_lhs.cidx(j); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3168 i < c_lhs.cidx(j+1); i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3169 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3170 stmp.data(kk) = c_lhs.data(i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3171 stmp.ridx(kk++) = c_lhs.ridx(i); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3172 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3173 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3174 stmp.cidx(j+1) = kk; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3175 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3176 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3177 stmp.maybe_compress(); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3178 lhs = stmp; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3179 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3180 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3181 else if (n == 0 && m == 0) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3182 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3183 if (! ((rhs_nr == 1 && rhs_nc == 1) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3184 || (rhs_nr == 0 || rhs_nc == 0))) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3185 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3186 (*current_liboctave_error_handler) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3187 ("A([], []) = X: X must be an empty matrix or a scalar"); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3188 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3189 retval = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3190 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3191 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3192 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3193 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3194 (*current_liboctave_error_handler) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3195 ("A(I, J) = X: X must be a scalar or the number of elements in I must"); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3196 (*current_liboctave_error_handler) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3197 ("match the number of rows in X and the number of elements in J must"); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3198 (*current_liboctave_error_handler) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3199 ("match the number of columns in X"); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3200 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3201 retval = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3202 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3203 } |
5164 | 3204 // idx_vector::freeze() printed an error message for us. |
3205 } | |
3206 else if (n_idx == 1) | |
3207 { | |
3208 int lhs_is_empty = lhs_nr == 0 || lhs_nc == 0; | |
3209 | |
3210 if (lhs_is_empty || (lhs_nr == 1 && lhs_nc == 1)) | |
3211 { | |
5275 | 3212 octave_idx_type lhs_len = lhs.length (); |
3213 | |
8677
095ae5e0a831
eliminte some compiler warnings
John W. Eaton <jwe@octave.org>
parents:
8527
diff
changeset
|
3214 // Called for side-effects on idx_i. |
095ae5e0a831
eliminte some compiler warnings
John W. Eaton <jwe@octave.org>
parents:
8527
diff
changeset
|
3215 idx_i.freeze (lhs_len, 0, true); |
5164 | 3216 |
3217 if (idx_i) | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3218 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3219 if (lhs_is_empty |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3220 && idx_i.is_colon () |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3221 && ! (rhs_nr == 1 || rhs_nc == 1)) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3222 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3223 (*current_liboctave_warning_with_id_handler) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3224 ("Octave:fortran-indexing", |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3225 "A(:) = X: X is not a vector or scalar"); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3226 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3227 else |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3228 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3229 octave_idx_type idx_nr = idx_i.orig_rows (); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3230 octave_idx_type idx_nc = idx_i.orig_columns (); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3231 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3232 if (! (rhs_nr == idx_nr && rhs_nc == idx_nc)) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3233 (*current_liboctave_warning_with_id_handler) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3234 ("Octave:fortran-indexing", |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3235 "A(I) = X: X does not have same shape as I"); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3236 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3237 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3238 if (! assign1 (lhs, rhs)) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3239 retval = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3240 } |
5164 | 3241 // idx_vector::freeze() printed an error message for us. |
3242 } | |
3243 else if (lhs_nr == 1) | |
3244 { | |
5781 | 3245 idx_i.freeze (lhs_nc, "vector", true); |
5164 | 3246 |
3247 if (idx_i) | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3248 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3249 if (! assign1 (lhs, rhs)) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3250 retval = 0; |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3251 } |
5164 | 3252 // idx_vector::freeze() printed an error message for us. |
3253 } | |
3254 else if (lhs_nc == 1) | |
3255 { | |
5781 | 3256 idx_i.freeze (lhs_nr, "vector", true); |
5164 | 3257 |
3258 if (idx_i) | |
3259 { | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3260 if (! assign1 (lhs, rhs)) |
5164 | 3261 retval = 0; |
3262 } | |
3263 // idx_vector::freeze() printed an error message for us. | |
3264 } | |
3265 else | |
3266 { | |
7573
755bf7ecc29b
eliminate one_zero stuff from idx_vector
John W. Eaton <jwe@octave.org>
parents:
7546
diff
changeset
|
3267 if (! idx_i.is_colon ()) |
5781 | 3268 (*current_liboctave_warning_with_id_handler) |
3269 ("Octave:fortran-indexing", "single index used for matrix"); | |
5164 | 3270 |
5275 | 3271 octave_idx_type lhs_len = lhs.length (); |
3272 | |
3273 octave_idx_type len = idx_i.freeze (lhs_nr * lhs_nc, "matrix"); | |
5164 | 3274 |
3275 if (idx_i) | |
3276 { | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7717
diff
changeset
|
3277 if (len == 0) |
5164 | 3278 { |
3279 if (! ((rhs_nr == 1 && rhs_nc == 1) | |
3280 || (rhs_nr == 0 || rhs_nc == 0))) | |
3281 (*current_liboctave_error_handler) | |
3282 ("A([]) = X: X must be an empty matrix or scalar"); | |
3283 } | |
3284 else if (len == rhs_nr * rhs_nc) | |
3285 { | |
5604 | 3286 octave_idx_type new_nzmx = lhs_nz; |
5603 | 3287 OCTAVE_LOCAL_BUFFER (octave_idx_type, rhs_idx, len); |
3288 | |
3289 if (! idx_i.is_colon ()) | |
3290 { | |
3291 // Ok here we have to be careful with the indexing, to | |
3292 // treat cases like "a([3,2,1]) = b", and still handle | |
3293 // the need for strict sorting of the sparse elements. | |
3294 | |
3295 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort *, sidx, | |
3296 len); | |
3297 OCTAVE_LOCAL_BUFFER (octave_idx_vector_sort, sidxX, | |
3298 len); | |
3299 | |
3300 for (octave_idx_type i = 0; i < len; i++) | |
3301 { | |
3302 sidx[i] = &sidxX[i]; | |
3303 sidx[i]->i = idx_i.elem(i); | |
3304 sidx[i]->idx = i; | |
3305 } | |
3306 | |
3307 OCTAVE_QUIT; | |
3308 octave_sort<octave_idx_vector_sort *> | |
3309 sort (octave_idx_vector_comp); | |
3310 | |
3311 sort.sort (sidx, len); | |
3312 | |
3313 intNDArray<octave_idx_type> new_idx (dim_vector (len,1)); | |
3314 | |
3315 for (octave_idx_type i = 0; i < len; i++) | |
3316 { | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8150
diff
changeset
|
3317 new_idx.xelem(i) = sidx[i]->i; |
5603 | 3318 rhs_idx[i] = sidx[i]->idx; |
3319 } | |
3320 | |
3321 idx_i = idx_vector (new_idx); | |
3322 } | |
3323 else | |
3324 for (octave_idx_type i = 0; i < len; i++) | |
3325 rhs_idx[i] = i; | |
5164 | 3326 |
3327 // First count the number of non-zero elements | |
5275 | 3328 for (octave_idx_type i = 0; i < len; i++) |
5164 | 3329 { |
3330 OCTAVE_QUIT; | |
3331 | |
5275 | 3332 octave_idx_type ii = idx_i.elem (i); |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3333 if (i < len - 1 && idx_i.elem (i + 1) == ii) |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3334 continue; |
5164 | 3335 if (ii < lhs_len && c_lhs.elem(ii) != LT ()) |
5604 | 3336 new_nzmx--; |
5603 | 3337 if (rhs.elem(rhs_idx[i]) != RT ()) |
5604 | 3338 new_nzmx++; |
5164 | 3339 } |
3340 | |
5604 | 3341 Sparse<LT> stmp (lhs_nr, lhs_nc, new_nzmx); |
5164 | 3342 |
5275 | 3343 octave_idx_type i = 0; |
3344 octave_idx_type ii = 0; | |
3345 octave_idx_type ic = 0; | |
5164 | 3346 if (i < lhs_nz) |
3347 { | |
3348 while (ic < lhs_nc && i >= c_lhs.cidx(ic+1)) | |
3349 ic++; | |
3350 ii = ic * lhs_nr + c_lhs.ridx(i); | |
3351 } | |
3352 | |
5275 | 3353 octave_idx_type j = 0; |
3354 octave_idx_type jj = idx_i.elem (j); | |
3355 octave_idx_type jr = jj % lhs_nr; | |
3356 octave_idx_type jc = (jj - jr) / lhs_nr; | |
3357 | |
3358 octave_idx_type kk = 0; | |
3359 octave_idx_type kc = 0; | |
5164 | 3360 |
3361 while (j < len || i < lhs_nz) | |
3362 { | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3363 if (j < len - 1 && idx_i.elem (j + 1) == jj) |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3364 { |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3365 j++; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3366 jj = idx_i.elem (j); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3367 jr = jj % lhs_nr; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3368 jc = (jj - jr) / lhs_nr; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3369 continue; |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3370 } |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3371 |
5164 | 3372 if (j == len || (i < lhs_nz && ii < jj)) |
3373 { | |
3374 while (kc <= ic) | |
3375 stmp.xcidx (kc++) = kk; | |
3376 stmp.xdata (kk) = c_lhs.data (i); | |
3377 stmp.xridx (kk++) = c_lhs.ridx (i); | |
3378 i++; | |
3379 while (ic < lhs_nc && i >= c_lhs.cidx(ic+1)) | |
3380 ic++; | |
3381 if (i < lhs_nz) | |
3382 ii = ic * lhs_nr + c_lhs.ridx(i); | |
3383 } | |
3384 else | |
3385 { | |
3386 while (kc <= jc) | |
3387 stmp.xcidx (kc++) = kk; | |
5603 | 3388 RT rtmp = rhs.elem (rhs_idx[j]); |
5164 | 3389 if (rtmp != RT ()) |
3390 { | |
3391 stmp.xdata (kk) = rtmp; | |
3392 stmp.xridx (kk++) = jr; | |
3393 } | |
3394 if (ii == jj) | |
3395 { | |
3396 i++; | |
3397 while (ic < lhs_nc && i >= c_lhs.cidx(ic+1)) | |
3398 ic++; | |
3399 if (i < lhs_nz) | |
3400 ii = ic * lhs_nr + c_lhs.ridx(i); | |
3401 } | |
3402 j++; | |
3403 if (j < len) | |
3404 { | |
3405 jj = idx_i.elem (j); | |
3406 jr = jj % lhs_nr; | |
3407 jc = (jj - jr) / lhs_nr; | |
3408 } | |
3409 } | |
3410 } | |
3411 | |
5275 | 3412 for (octave_idx_type iidx = kc; iidx < lhs_nc+1; iidx++) |
5603 | 3413 stmp.xcidx(iidx) = kk; |
5164 | 3414 |
3415 lhs = stmp; | |
3416 } | |
3417 else if (rhs_nr == 1 && rhs_nc == 1) | |
3418 { | |
3419 RT scalar = rhs.elem (0, 0); | |
5604 | 3420 octave_idx_type new_nzmx = lhs_nz; |
5603 | 3421 idx_i.sort (true); |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3422 len = idx_i.length (len); |
5164 | 3423 |
3424 // First count the number of non-zero elements | |
3425 if (scalar != RT ()) | |
5604 | 3426 new_nzmx += len; |
5275 | 3427 for (octave_idx_type i = 0; i < len; i++) |
5164 | 3428 { |
3429 OCTAVE_QUIT; | |
5275 | 3430 octave_idx_type ii = idx_i.elem (i); |
5164 | 3431 if (ii < lhs_len && c_lhs.elem(ii) != LT ()) |
5604 | 3432 new_nzmx--; |
5164 | 3433 } |
3434 | |
5604 | 3435 Sparse<LT> stmp (lhs_nr, lhs_nc, new_nzmx); |
5164 | 3436 |
5275 | 3437 octave_idx_type i = 0; |
3438 octave_idx_type ii = 0; | |
3439 octave_idx_type ic = 0; | |
5164 | 3440 if (i < lhs_nz) |
3441 { | |
3442 while (ic < lhs_nc && i >= c_lhs.cidx(ic+1)) | |
3443 ic++; | |
3444 ii = ic * lhs_nr + c_lhs.ridx(i); | |
3445 } | |
3446 | |
5275 | 3447 octave_idx_type j = 0; |
3448 octave_idx_type jj = idx_i.elem (j); | |
3449 octave_idx_type jr = jj % lhs_nr; | |
3450 octave_idx_type jc = (jj - jr) / lhs_nr; | |
3451 | |
3452 octave_idx_type kk = 0; | |
3453 octave_idx_type kc = 0; | |
5164 | 3454 |
3455 while (j < len || i < lhs_nz) | |
3456 { | |
3457 if (j == len || (i < lhs_nz && ii < jj)) | |
3458 { | |
3459 while (kc <= ic) | |
3460 stmp.xcidx (kc++) = kk; | |
3461 stmp.xdata (kk) = c_lhs.data (i); | |
3462 stmp.xridx (kk++) = c_lhs.ridx (i); | |
3463 i++; | |
3464 while (ic < lhs_nc && i >= c_lhs.cidx(ic+1)) | |
3465 ic++; | |
3466 if (i < lhs_nz) | |
3467 ii = ic * lhs_nr + c_lhs.ridx(i); | |
3468 } | |
3469 else | |
3470 { | |
3471 while (kc <= jc) | |
3472 stmp.xcidx (kc++) = kk; | |
3473 if (scalar != RT ()) | |
3474 { | |
3475 stmp.xdata (kk) = scalar; | |
3476 stmp.xridx (kk++) = jr; | |
3477 } | |
3478 if (ii == jj) | |
3479 { | |
3480 i++; | |
3481 while (ic < lhs_nc && i >= c_lhs.cidx(ic+1)) | |
3482 ic++; | |
3483 if (i < lhs_nz) | |
3484 ii = ic * lhs_nr + c_lhs.ridx(i); | |
3485 } | |
3486 j++; | |
3487 if (j < len) | |
3488 { | |
3489 jj = idx_i.elem (j); | |
3490 jr = jj % lhs_nr; | |
3491 jc = (jj - jr) / lhs_nr; | |
3492 } | |
3493 } | |
3494 } | |
3495 | |
5275 | 3496 for (octave_idx_type iidx = kc; iidx < lhs_nc+1; iidx++) |
5164 | 3497 stmp.xcidx(iidx) = kk; |
3498 | |
3499 lhs = stmp; | |
3500 } | |
3501 else | |
3502 { | |
3503 (*current_liboctave_error_handler) | |
3504 ("A(I) = X: X must be a scalar or a matrix with the same size as I"); | |
3505 | |
3506 retval = 0; | |
3507 } | |
3508 } | |
3509 // idx_vector::freeze() printed an error message for us. | |
3510 } | |
3511 } | |
3512 else | |
3513 { | |
3514 (*current_liboctave_error_handler) | |
3515 ("invalid number of indices for matrix expression"); | |
3516 | |
3517 retval = 0; | |
3518 } | |
3519 | |
3520 lhs.clear_index (); | |
3521 | |
3522 return retval; | |
3523 } | |
3524 | |
7356 | 3525 /* |
3526 * Tests | |
3527 * | |
3528 | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3529 %!function x = set_slice(x, dim, slice, arg) |
7356 | 3530 %! switch dim |
3531 %! case 11 | |
3532 %! x(slice) = 2; | |
3533 %! case 21 | |
3534 %! x(slice, :) = 2; | |
3535 %! case 22 | |
3536 %! x(:, slice) = 2; | |
3537 %! otherwise | |
3538 %! error("invalid dim, '%d'", dim); | |
3539 %! endswitch | |
3540 %! endfunction | |
3541 | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3542 %!function x = set_slice2(x, dim, slice) |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3543 %! switch dim |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3544 %! case 11 |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3545 %! x(slice) = 2 * ones (size(slice)); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3546 %! case 21 |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3547 %! x(slice, :) = 2 * ones (length(slice), columns (x)); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3548 %! case 22 |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3549 %! x(:, slice) = 2 * ones (rows (x), length(slice)); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3550 %! otherwise |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3551 %! error("invalid dim, '%d'", dim); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3552 %! endswitch |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3553 %! endfunction |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3554 |
7356 | 3555 %!function test_sparse_slice(size, dim, slice) |
3556 %! x = ones(size); | |
3557 %! s = set_slice(sparse(x), dim, slice); | |
3558 %! f = set_slice(x, dim, slice); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3559 %! assert (nnz(s), nnz(f)); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3560 %! assert(full(s), f); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3561 %! s = set_slice2(sparse(x), dim, slice); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3562 %! f = set_slice2(x, dim, slice); |
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3563 %! assert (nnz(s), nnz(f)); |
7356 | 3564 %! assert(full(s), f); |
3565 %! endfunction | |
3566 | |
3567 #### 1d indexing | |
3568 | |
3569 ## size = [2 0] | |
3570 %!test test_sparse_slice([2 0], 11, []); | |
3571 %!assert(set_slice(sparse(ones([2 0])), 11, 1), sparse([2 0]')); # sparse different from full | |
3572 %!assert(set_slice(sparse(ones([2 0])), 11, 2), sparse([0 2]')); # sparse different from full | |
3573 %!assert(set_slice(sparse(ones([2 0])), 11, 3), sparse([0 0 2]')); # sparse different from full | |
3574 %!assert(set_slice(sparse(ones([2 0])), 11, 4), sparse([0 0 0 2]')); # sparse different from full | |
3575 | |
3576 ## size = [0 2] | |
3577 %!test test_sparse_slice([0 2], 11, []); | |
3578 %!assert(set_slice(sparse(ones([0 2])), 11, 1), sparse(1,2)); # sparse different from full | |
3579 %!test test_sparse_slice([0 2], 11, 2); | |
3580 %!test test_sparse_slice([0 2], 11, 3); | |
3581 %!test test_sparse_slice([0 2], 11, 4); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3582 %!test test_sparse_slice([0 2], 11, [4, 4]); |
7356 | 3583 |
3584 ## size = [2 1] | |
3585 %!test test_sparse_slice([2 1], 11, []); | |
3586 %!test test_sparse_slice([2 1], 11, 1); | |
3587 %!test test_sparse_slice([2 1], 11, 2); | |
3588 %!test test_sparse_slice([2 1], 11, 3); | |
3589 %!test test_sparse_slice([2 1], 11, 4); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3590 %!test test_sparse_slice([2 1], 11, [4, 4]); |
7356 | 3591 |
3592 ## size = [1 2] | |
3593 %!test test_sparse_slice([1 2], 11, []); | |
3594 %!test test_sparse_slice([1 2], 11, 1); | |
3595 %!test test_sparse_slice([1 2], 11, 2); | |
3596 %!test test_sparse_slice([1 2], 11, 3); | |
3597 %!test test_sparse_slice([1 2], 11, 4); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3598 %!test test_sparse_slice([1 2], 11, [4, 4]); |
7356 | 3599 |
3600 ## size = [2 2] | |
3601 %!test test_sparse_slice([2 2], 11, []); | |
3602 %!test test_sparse_slice([2 2], 11, 1); | |
3603 %!test test_sparse_slice([2 2], 11, 2); | |
3604 %!test test_sparse_slice([2 2], 11, 3); | |
3605 %!test test_sparse_slice([2 2], 11, 4); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3606 %!test test_sparse_slice([2 2], 11, [4, 4]); |
7356 | 3607 # These 2 errors are the same as in the full case |
3608 %!error <invalid matrix index = 5> set_slice(sparse(ones([2 2])), 11, 5); | |
3609 %!error <invalid matrix index = 6> set_slice(sparse(ones([2 2])), 11, 6); | |
3610 | |
3611 | |
3612 #### 2d indexing | |
3613 | |
3614 ## size = [2 0] | |
3615 %!test test_sparse_slice([2 0], 21, []); | |
3616 %!test test_sparse_slice([2 0], 21, 1); | |
3617 %!test test_sparse_slice([2 0], 21, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3618 %!test test_sparse_slice([2 0], 21, [2,2]); |
7356 | 3619 %!assert(set_slice(sparse(ones([2 0])), 21, 3), sparse(2,0)); # sparse different from full |
3620 %!assert(set_slice(sparse(ones([2 0])), 21, 4), sparse(2,0)); # sparse different from full | |
3621 %!test test_sparse_slice([2 0], 22, []); | |
3622 %!test test_sparse_slice([2 0], 22, 1); | |
3623 %!test test_sparse_slice([2 0], 22, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3624 %!test test_sparse_slice([2 0], 22, [2,2]); |
7356 | 3625 %!assert(set_slice(sparse(ones([2 0])), 22, 3), sparse([0 0 2;0 0 2])); # sparse different from full |
3626 %!assert(set_slice(sparse(ones([2 0])), 22, 4), sparse([0 0 0 2;0 0 0 2])); # sparse different from full | |
3627 | |
3628 ## size = [0 2] | |
3629 %!test test_sparse_slice([0 2], 21, []); | |
3630 %!test test_sparse_slice([0 2], 21, 1); | |
3631 %!test test_sparse_slice([0 2], 21, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3632 %!test test_sparse_slice([0 2], 21, [2,2]); |
7356 | 3633 %!assert(set_slice(sparse(ones([0 2])), 21, 3), sparse([0 0;0 0;2 2])); # sparse different from full |
3634 %!assert(set_slice(sparse(ones([0 2])), 21, 4), sparse([0 0;0 0;0 0;2 2])); # sparse different from full | |
3635 %!test test_sparse_slice([0 2], 22, []); | |
3636 %!test test_sparse_slice([0 2], 22, 1); | |
3637 %!test test_sparse_slice([0 2], 22, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3638 %!test test_sparse_slice([0 2], 22, [2,2]); |
7356 | 3639 %!assert(set_slice(sparse(ones([0 2])), 22, 3), sparse(0,2)); # sparse different from full |
3640 %!assert(set_slice(sparse(ones([0 2])), 22, 4), sparse(0,2)); # sparse different from full | |
3641 | |
3642 ## size = [2 1] | |
3643 %!test test_sparse_slice([2 1], 21, []); | |
3644 %!test test_sparse_slice([2 1], 21, 1); | |
3645 %!test test_sparse_slice([2 1], 21, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3646 %!test test_sparse_slice([2 1], 21, [2,2]); |
7356 | 3647 %!test test_sparse_slice([2 1], 21, 3); |
3648 %!test test_sparse_slice([2 1], 21, 4); | |
3649 %!test test_sparse_slice([2 1], 22, []); | |
3650 %!test test_sparse_slice([2 1], 22, 1); | |
3651 %!test test_sparse_slice([2 1], 22, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3652 %!test test_sparse_slice([2 1], 22, [2,2]); |
7356 | 3653 %!test test_sparse_slice([2 1], 22, 3); |
3654 %!test test_sparse_slice([2 1], 22, 4); | |
3655 | |
3656 ## size = [1 2] | |
3657 %!test test_sparse_slice([1 2], 21, []); | |
3658 %!test test_sparse_slice([1 2], 21, 1); | |
3659 %!test test_sparse_slice([1 2], 21, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3660 %!test test_sparse_slice([1 2], 21, [2,2]); |
7356 | 3661 %!test test_sparse_slice([1 2], 21, 3); |
3662 %!test test_sparse_slice([1 2], 21, 4); | |
3663 %!test test_sparse_slice([1 2], 22, []); | |
3664 %!test test_sparse_slice([1 2], 22, 1); | |
3665 %!test test_sparse_slice([1 2], 22, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3666 %!test test_sparse_slice([1 2], 22, [2,2]); |
7356 | 3667 %!test test_sparse_slice([1 2], 22, 3); |
3668 %!test test_sparse_slice([1 2], 22, 4); | |
3669 | |
3670 ## size = [2 2] | |
3671 %!test test_sparse_slice([2 2], 21, []); | |
3672 %!test test_sparse_slice([2 2], 21, 1); | |
3673 %!test test_sparse_slice([2 2], 21, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3674 %!test test_sparse_slice([2 2], 21, [2,2]); |
7356 | 3675 %!test test_sparse_slice([2 2], 21, 3); |
3676 %!test test_sparse_slice([2 2], 21, 4); | |
3677 %!test test_sparse_slice([2 2], 22, []); | |
3678 %!test test_sparse_slice([2 2], 22, 1); | |
3679 %!test test_sparse_slice([2 2], 22, 2); | |
7546
4249c6fb6e09
Treat repeated indices in the sparse assignments
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
3680 %!test test_sparse_slice([2 2], 22, [2,2]); |
7356 | 3681 %!test test_sparse_slice([2 2], 22, 3); |
3682 %!test test_sparse_slice([2 2], 22, 4); | |
3683 | |
3684 */ | |
3685 | |
5164 | 3686 template <class T> |
3687 void | |
3688 Sparse<T>::print_info (std::ostream& os, const std::string& prefix) const | |
3689 { | |
3690 os << prefix << "rep address: " << rep << "\n" | |
5604 | 3691 << prefix << "rep->nzmx: " << rep->nzmx << "\n" |
5164 | 3692 << prefix << "rep->nrows: " << rep->nrows << "\n" |
3693 << prefix << "rep->ncols: " << rep->ncols << "\n" | |
3694 << prefix << "rep->data: " << static_cast<void *> (rep->d) << "\n" | |
3695 << prefix << "rep->ridx: " << static_cast<void *> (rep->r) << "\n" | |
3696 << prefix << "rep->cidx: " << static_cast<void *> (rep->c) << "\n" | |
3697 << prefix << "rep->count: " << rep->count << "\n"; | |
3698 } | |
3699 | |
3700 /* | |
3701 ;;; Local Variables: *** | |
3702 ;;; mode: C++ *** | |
3703 ;;; End: *** | |
3704 */ |