Mercurial > octave-nkf
annotate liboctave/DiagArray2.cc @ 8523:ad3afaaa19c1
implement non-copying contiguous range indexing
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 15 Jan 2009 07:22:24 +0100 |
parents | e3c9102431a9 |
children | 937921654627 |
rev | line source |
---|---|
1993 | 1 // Template array classes |
1988 | 2 /* |
3 | |
7017 | 4 Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2007 |
5 John W. Eaton | |
1988 | 6 |
7 This file is part of Octave. | |
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. | |
1988 | 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/>. | |
1988 | 22 |
23 */ | |
24 | |
25 #ifdef HAVE_CONFIG_H | |
26 #include <config.h> | |
27 #endif | |
28 | |
29 #include <cassert> | |
30 | |
3503 | 31 #include <iostream> |
1988 | 32 |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
33 #include <algorithm> |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
34 |
1988 | 35 #include "DiagArray2.h" |
36 | |
37 #include "lo-error.h" | |
38 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
39 template <class T> |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
40 Array<T> |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
41 DiagArray2<T>::diag (octave_idx_type k) const |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
42 { |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
43 Array<T> d; |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
44 |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
45 if (k == 0) |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
46 { |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
47 // The main diagonal is shallow-copied. |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
48 d = *this; |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
49 d.dimensions = dim_vector (length ()); |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
50 } |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
51 else if (k > 0 && k < cols ()) |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
52 d = Array<T> (std::min (cols () - k, rows ()), T ()); |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
53 else if (k < 0 && -k < rows ()) |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
54 d = Array<T> (std::min (rows () + k, cols ()), T ()); |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
55 else |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
56 (*current_liboctave_error_handler) |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
57 ("diag: requested diagonal out of range"); |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
58 |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
59 return d; |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
60 } |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
61 |
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
62 template <class T> |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
63 DiagArray2<T> |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
64 DiagArray2<T>::transpose (void) const |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
65 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
66 DiagArray2<T> retval (*this); |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
67 retval.dimensions = dim_vector (dim2 (), dim1 ()); |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
68 return retval; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
69 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
70 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
71 template <class T> |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
72 DiagArray2<T> |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
73 DiagArray2<T>::hermitian (T (* fcn) (const T&)) const |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
74 { |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
75 DiagArray2<T> retval (dim2 (), dim1 ()); |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
76 const T *p = this->data (); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
77 T *q = retval.fortran_vec (); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
78 for (octave_idx_type i = 0; i < this->length (); i++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
79 q [i] = fcn (p [i]); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
80 return retval; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
81 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
82 |
1988 | 83 // A two-dimensional array with diagonal elements only. |
84 | |
85 template <class T> | |
86 T | |
5275 | 87 DiagArray2<T>::checkelem (octave_idx_type r, octave_idx_type c) const |
1988 | 88 { |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
89 if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ()) |
1988 | 90 { |
3928 | 91 (*current_liboctave_error_handler) ("range error in DiagArray2"); |
3333 | 92 return T (); |
1988 | 93 } |
94 return (r == c) ? Array<T>::xelem (r) : T (0); | |
95 } | |
96 | |
97 template <class T> | |
98 void | |
5275 | 99 DiagArray2<T>::resize (octave_idx_type r, octave_idx_type c) |
1988 | 100 { |
101 if (r < 0 || c < 0) | |
102 { | |
103 (*current_liboctave_error_handler) ("can't resize to negative dimensions"); | |
104 return; | |
105 } | |
106 | |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
107 if (r == dim1 () && c == dim2 ()) |
1988 | 108 return; |
109 | |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8375
diff
changeset
|
110 // FIXME: this is a mess. DiagArray2 really needs a rewrite. |
4323 | 111 typename Array<T>::ArrayRep *old_rep = Array<T>::rep; |
4645 | 112 const T *old_data = this->data (); |
5275 | 113 octave_idx_type old_len = this->length (); |
1988 | 114 |
5275 | 115 octave_idx_type new_len = r < c ? r : c; |
1988 | 116 |
4323 | 117 Array<T>::rep = new typename Array<T>::ArrayRep (new_len); |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8375
diff
changeset
|
118 Array<T>::slice_data = Array<T>::rep->data; |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8375
diff
changeset
|
119 Array<T>::slice_len = Array<T>::rep->len; |
1988 | 120 |
4645 | 121 this->dimensions = dim_vector (r, c); |
1988 | 122 |
123 if (old_data && old_len > 0) | |
124 { | |
5275 | 125 octave_idx_type min_len = old_len < new_len ? old_len : new_len; |
1988 | 126 |
5275 | 127 for (octave_idx_type i = 0; i < min_len; i++) |
1988 | 128 xelem (i, i) = old_data[i]; |
129 } | |
130 | |
131 if (--old_rep->count <= 0) | |
132 delete old_rep; | |
133 } | |
134 | |
135 template <class T> | |
136 void | |
5275 | 137 DiagArray2<T>::resize (octave_idx_type r, octave_idx_type c, const T& val) |
1988 | 138 { |
139 if (r < 0 || c < 0) | |
140 { | |
141 (*current_liboctave_error_handler) ("can't resize to negative dimensions"); | |
142 return; | |
143 } | |
144 | |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
145 if (r == dim1 () && c == dim2 ()) |
1988 | 146 return; |
147 | |
4323 | 148 typename Array<T>::ArrayRep *old_rep = Array<T>::rep; |
4645 | 149 const T *old_data = this->data (); |
5275 | 150 octave_idx_type old_len = this->length (); |
1988 | 151 |
5275 | 152 octave_idx_type new_len = r < c ? r : c; |
1988 | 153 |
4323 | 154 Array<T>::rep = new typename Array<T>::ArrayRep (new_len); |
1988 | 155 |
4645 | 156 this->dimensions = dim_vector (r, c); |
1988 | 157 |
5275 | 158 octave_idx_type min_len = old_len < new_len ? old_len : new_len; |
1988 | 159 |
160 if (old_data && old_len > 0) | |
161 { | |
5275 | 162 for (octave_idx_type i = 0; i < min_len; i++) |
1988 | 163 xelem (i, i) = old_data[i]; |
164 } | |
165 | |
5275 | 166 for (octave_idx_type i = min_len; i < new_len; i++) |
1988 | 167 xelem (i, i) = val; |
168 | |
169 if (--old_rep->count <= 0) | |
170 delete old_rep; | |
171 } | |
172 | |
173 /* | |
174 ;;; Local Variables: *** | |
175 ;;; mode: C++ *** | |
176 ;;; End: *** | |
177 */ |