759
|
1 // tc-inlines.h -*- C++ -*- |
1
|
2 /* |
|
3 |
1009
|
4 Copyright (C) 1992, 1993, 1994, 1995 John W. Eaton |
1
|
5 |
|
6 This file is part of Octave. |
|
7 |
|
8 Octave is free software; you can redistribute it and/or modify it |
|
9 under the terms of the GNU General Public License as published by the |
|
10 Free Software Foundation; either version 2, or (at your option) any |
|
11 later version. |
|
12 |
|
13 Octave is distributed in the hope that it will be useful, but WITHOUT |
|
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
16 for more details. |
|
17 |
|
18 You should have received a copy of the GNU General Public License |
|
19 along with Octave; see the file COPYING. If not, write to the Free |
|
20 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|
21 |
|
22 */ |
|
23 |
|
24 // Just a coupla more helper functions. |
|
25 |
|
26 static inline int |
|
27 tree_to_mat_idx (double x) |
|
28 { |
|
29 if (x > 0) |
|
30 return ((int) (x + 0.5) - 1); |
|
31 else |
|
32 return ((int) (x - 0.5) - 1); |
|
33 } |
|
34 |
|
35 static inline int |
|
36 range_max_check (int i, int imax) |
|
37 { |
|
38 i++; |
|
39 if (i > imax) |
|
40 { |
|
41 error ("matrix index = %d exceeds maximum dimension = %d", i, imax); |
143
|
42 return -1; |
1
|
43 } |
143
|
44 return 0; |
1
|
45 } |
|
46 |
|
47 static inline int |
|
48 range_max_check (int i, int j, int nr, int nc) |
|
49 { |
143
|
50 int status = 0; |
1
|
51 i++; |
|
52 if (i > nr) |
|
53 { |
|
54 error ("matrix row index = %d exceeds maximum row dimension = %d", |
|
55 i, nr); |
143
|
56 status = -1; |
1
|
57 } |
|
58 |
|
59 j++; |
|
60 if (j > nc) |
|
61 { |
|
62 error ("matrix column index = %d exceeds maximum column dimension = %d", |
143
|
63 j, nc); |
|
64 status = -1; |
1
|
65 } |
143
|
66 return status; |
1
|
67 } |
|
68 |
|
69 static inline int |
|
70 indexed_assign_conforms (int lhs_nr, int lhs_nc, int rhs_nr, int rhs_nc) |
|
71 { |
|
72 return (lhs_nr == rhs_nr && lhs_nc == rhs_nc); |
|
73 } |
|
74 |
|
75 static inline int |
212
|
76 is_one_zero (const Range& r) |
|
77 { |
|
78 double b = r.base (); |
|
79 double l = r.limit (); |
|
80 return (r.nelem () == 2 && NINT (b) == 1 && NINT (l) == 0); |
|
81 } |
|
82 |
|
83 static inline int |
1
|
84 is_zero_one (const Range& r) |
|
85 { |
|
86 double b = r.base (); |
|
87 double l = r.limit (); |
212
|
88 return (r.nelem () == 2 && NINT (b) == 0 && NINT (l) == 1); |
1
|
89 } |
|
90 |
143
|
91 static inline int |
1
|
92 index_check (int i, char *rc) |
|
93 { |
|
94 if (i < 0) |
|
95 { |
|
96 error ("invalid %s index = %d", rc, i+1); |
143
|
97 return -1; |
1
|
98 } |
143
|
99 return 0; |
1
|
100 } |
|
101 |
143
|
102 static inline int |
212
|
103 index_check (const Range& r, char *rc) |
1
|
104 { |
|
105 if (r.nelem () < 1) |
|
106 { |
|
107 error ("range invalid as %s index", rc); |
143
|
108 return -1; |
1
|
109 } |
|
110 |
212
|
111 int imin = tree_to_mat_idx (r.min ()); |
143
|
112 |
212
|
113 if (imin < 0) |
1
|
114 { |
212
|
115 error ("invalid %s index = %d", rc, imin+1); |
143
|
116 return -1; |
1
|
117 } |
|
118 |
143
|
119 return 0; |
1
|
120 } |
|
121 |
143
|
122 static inline int |
1
|
123 fortran_row (int i, int nr) |
|
124 { |
|
125 int r; |
|
126 r = i % nr; |
|
127 if (r == 0) |
|
128 r = nr; |
|
129 return r; |
|
130 } |
|
131 |
|
132 static inline int |
|
133 fortran_column (int i, int nr) |
|
134 { |
|
135 int c; |
|
136 int r; |
|
137 r = fortran_row (i, nr); |
|
138 c = (i - r) / nr + 1; |
|
139 return c; |
|
140 } |
|
141 |
744
|
142 // How about a few macros? |
|
143 |
1206
|
144 #ifndef TC_REP |
744
|
145 #define TC_REP tree_constant::tree_constant_rep |
1206
|
146 #endif |
744
|
147 |
|
148 #ifndef MAX |
|
149 #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
|
150 #endif |
|
151 |
|
152 #ifndef MIN |
|
153 #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
|
154 #endif |
|
155 |
|
156 #ifndef ABS |
|
157 #define ABS(x) (((x) < 0) ? (-x) : (x)) |
|
158 #endif |
|
159 |
|
160 // The following are used by some of the functions in the |
|
161 // tree_constant_rep class that must deal with real and complex |
|
162 // matrices. This was not done with overloaded or virtual functions |
|
163 // from the Matrix class because there is no clean way to do that -- |
|
164 // the necessary functions (like elem) need to return values of |
|
165 // different types... |
|
166 |
|
167 // Given a tree_constant, and the names to be used for the real and |
|
168 // complex matrix and their dimensions, declare a real or complex |
|
169 // matrix, and initialize it from the tree_constant. Note that m, cm, |
|
170 // nr, and nc must not be previously declared, and they must not be |
|
171 // expressions. Since only one of the matrices will be defined after |
|
172 // this macro is used, only one set of dimesions is declared. |
|
173 |
|
174 // This macro only makes sense inside a friend or member function of |
|
175 // the tree_constant_rep class |
|
176 |
|
177 #define REP_RHS_MATRIX(tc,m,cm,nr,nc) \ |
|
178 int nr = 0; \ |
|
179 int nc = 0; \ |
|
180 Matrix m; \ |
|
181 ComplexMatrix cm; \ |
1217
|
182 if ((tc).is_real_type ()) \ |
|
183 { \ |
|
184 m = (tc).matrix_value (); \ |
|
185 nr = (m).rows (); \ |
|
186 nc = (m).columns (); \ |
|
187 } \ |
|
188 else if ((tc).is_complex_type ()) \ |
744
|
189 { \ |
|
190 cm = (tc).complex_matrix_value (); \ |
|
191 nr = (cm).rows (); \ |
|
192 nc = (cm).columns (); \ |
|
193 } \ |
1217
|
194 else \ |
744
|
195 { \ |
1217
|
196 panic_impossible (); \ |
744
|
197 } \ |
1217
|
198 if (error_state) \ |
|
199 return; |
744
|
200 |
|
201 // Assign a real or complex value to a tree_constant. |
|
202 // |
|
203 // This macro only makes sense inside a friend or member function of |
|
204 // the tree_constant_rep class. |
|
205 |
|
206 #define REP_ELEM_ASSIGN(i,j,rval,cval,real_type) \ |
|
207 do \ |
|
208 { \ |
|
209 if (type_tag == TC_REP::matrix_constant) \ |
|
210 { \ |
|
211 if (real_type) \ |
|
212 matrix->elem ((i), (j)) = (rval); \ |
|
213 else \ |
768
|
214 panic_impossible (); \ |
744
|
215 } \ |
|
216 else \ |
|
217 { \ |
|
218 if (real_type) \ |
|
219 complex_matrix->elem ((i), (j)) = (rval); \ |
|
220 else \ |
|
221 complex_matrix->elem ((i), (j)) = (cval); \ |
|
222 } \ |
|
223 } \ |
|
224 while (0) |
|
225 |
|
226 // Given a real and complex matrix and row and column dimensions, |
|
227 // declare both and size one of them. Only one of the matrices should |
|
228 // be used after this macro has been used. |
|
229 |
|
230 // This macro only makes sense inside a friend or member function of |
|
231 // the tree_constant_rep class. |
|
232 |
|
233 #define CRMATRIX(m,cm,nr,nc) \ |
|
234 Matrix m; \ |
|
235 ComplexMatrix cm; \ |
|
236 if (type_tag == TC_REP::matrix_constant) \ |
|
237 (m).resize ((nr), (nc)); \ |
|
238 else if (type_tag == complex_matrix_constant) \ |
|
239 (cm).resize ((nr), (nc)); \ |
|
240 else \ |
768
|
241 panic_impossible (); \ |
744
|
242 |
|
243 // Assign a real or complex matrix to a tree constant. |
|
244 |
|
245 // This macro only makes sense inside a friend or member function of |
|
246 // the tree_constant_rep class. |
|
247 |
|
248 #define ASSIGN_CRMATRIX_TO(tc,m,cm) \ |
|
249 do \ |
|
250 { \ |
|
251 if (type_tag == matrix_constant) \ |
|
252 tc = tree_constant (m); \ |
|
253 else \ |
|
254 tc = tree_constant (cm); \ |
|
255 } \ |
|
256 while (0) |
|
257 |
|
258 // Assign an element of this tree_constant_rep's real or complex |
|
259 // matrix to another real or complex matrix. |
|
260 |
|
261 // This macro only makes sense inside a friend or member function of |
|
262 // the tree_constant_rep class. |
|
263 |
|
264 #define CRMATRIX_ASSIGN_REP_ELEM(m,cm,i1,j1,i2,j2) \ |
|
265 do \ |
|
266 { \ |
|
267 if (type_tag == matrix_constant) \ |
|
268 (m).elem ((i1), (j1)) = matrix->elem ((i2), (j2)); \ |
|
269 else \ |
|
270 (cm).elem ((i1), (j1)) = complex_matrix->elem ((i2), (j2)); \ |
|
271 } \ |
|
272 while (0) |
|
273 |
|
274 // Assign a value to an element of a real or complex matrix. Assumes |
|
275 // that the lhs and rhs are either both real or both complex types. |
|
276 |
|
277 #define CRMATRIX_ASSIGN_ELEM(m,cm,i,j,rval,cval,real_type) \ |
|
278 do \ |
|
279 { \ |
|
280 if (real_type) \ |
|
281 (m).elem ((i), (j)) = (rval); \ |
|
282 else \ |
|
283 (cm).elem ((i), (j)) = (cval); \ |
|
284 } \ |
|
285 while (0) |
|
286 |
|
287 |
|
288 // One more... |
|
289 |
|
290 static inline int |
|
291 valid_scalar_indices (const Octave_object& args) |
|
292 { |
|
293 int nargin = args.length (); |
|
294 |
|
295 return ((nargin == 2 |
|
296 && args(1).valid_as_scalar_index () |
|
297 && args(0).valid_as_scalar_index ()) |
|
298 || (nargin == 1 |
|
299 && args(0).valid_as_scalar_index ())); |
|
300 } |
|
301 |
1041
|
302 static inline int |
|
303 valid_zero_index (const Octave_object& args) |
|
304 { |
|
305 int nargin = args.length (); |
|
306 |
|
307 return ((nargin == 2 |
|
308 && args(1).valid_as_zero_index () |
|
309 && args(0).valid_as_zero_index ()) |
|
310 || (nargin == 1 |
|
311 && args(0).valid_as_zero_index ())); |
|
312 } |
|
313 |
1
|
314 /* |
|
315 ;;; Local Variables: *** |
|
316 ;;; mode: C++ *** |
|
317 ;;; page-delimiter: "^/\\*" *** |
|
318 ;;; End: *** |
|
319 */ |