Mercurial > hg > octave-avbm
comparison src/minmax.cc @ 515:e078f05f4aac
[project @ 1994-07-13 02:31:31 by jwe]
Initial revision
author | jwe |
---|---|
date | Wed, 13 Jul 1994 02:31:31 +0000 |
parents | |
children | b9284136189a |
comparison
equal
deleted
inserted
replaced
514:20d2061944ee | 515:e078f05f4aac |
---|---|
1 // f-minmax.cc -*- C++ -*- | |
2 /* | |
3 | |
4 Copyright (C) 1994 John W. Eaton | |
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 #ifdef HAVE_CONFIG_H | |
25 #include "config.h" | |
26 #endif | |
27 | |
28 #include <math.h> | |
29 | |
30 #include "tree-const.h" | |
31 #include "error.h" | |
32 #include "f-minmax.h" | |
33 | |
34 #ifndef MAX | |
35 #define MAX(a,b) ((a) > (b) ? (a) : (b)) | |
36 #endif | |
37 | |
38 #ifndef MIN | |
39 #define MIN(a,b) ((a) < (b) ? (a) : (b)) | |
40 #endif | |
41 | |
42 static Matrix | |
43 min (const Matrix& a, const Matrix& b) | |
44 { | |
45 int nr = a.rows (); | |
46 int nc = a.columns (); | |
47 if (nr != b.rows () || nc != b.columns ()) | |
48 { | |
49 error ("two-arg min expecting args of same size"); | |
50 return Matrix (); | |
51 } | |
52 | |
53 Matrix result (nr, nc); | |
54 | |
55 for (int j = 0; j < nc; j++) | |
56 for (int i = 0; i < nr; i++) | |
57 { | |
58 double a_elem = a.elem (i, j); | |
59 double b_elem = b.elem (i, j); | |
60 result.elem (i, j) = MIN (a_elem, b_elem); | |
61 } | |
62 | |
63 return result; | |
64 } | |
65 | |
66 static ComplexMatrix | |
67 min (const ComplexMatrix& a, const ComplexMatrix& b) | |
68 { | |
69 int nr = a.rows (); | |
70 int nc = a.columns (); | |
71 if (nr != b.rows () || nc != b.columns ()) | |
72 { | |
73 error ("two-arg min expecting args of same size"); | |
74 return ComplexMatrix (); | |
75 } | |
76 | |
77 ComplexMatrix result (nr, nc); | |
78 | |
79 for (int j = 0; j < nc; j++) | |
80 for (int i = 0; i < nr; i++) | |
81 { | |
82 double abs_a_elem = abs (a.elem (i, j)); | |
83 double abs_b_elem = abs (b.elem (i, j)); | |
84 if (abs_a_elem < abs_b_elem) | |
85 result.elem (i, j) = a.elem (i, j); | |
86 else | |
87 result.elem (i, j) = b.elem (i, j); | |
88 } | |
89 | |
90 return result; | |
91 } | |
92 | |
93 static Matrix | |
94 max (const Matrix& a, const Matrix& b) | |
95 { | |
96 int nr = a.rows (); | |
97 int nc = a.columns (); | |
98 if (nr != b.rows () || nc != b.columns ()) | |
99 { | |
100 error ("two-arg max expecting args of same size"); | |
101 return Matrix (); | |
102 } | |
103 | |
104 Matrix result (nr, nc); | |
105 | |
106 for (int j = 0; j < nc; j++) | |
107 for (int i = 0; i < nr; i++) | |
108 { | |
109 double a_elem = a.elem (i, j); | |
110 double b_elem = b.elem (i, j); | |
111 result.elem (i, j) = MAX (a_elem, b_elem); | |
112 } | |
113 | |
114 return result; | |
115 } | |
116 | |
117 static ComplexMatrix | |
118 max (const ComplexMatrix& a, const ComplexMatrix& b) | |
119 { | |
120 int nr = a.rows (); | |
121 int nc = a.columns (); | |
122 if (nr != b.rows () || nc != b.columns ()) | |
123 { | |
124 error ("two-arg max expecting args of same size"); | |
125 return ComplexMatrix (); | |
126 } | |
127 | |
128 ComplexMatrix result (nr, nc); | |
129 | |
130 for (int j = 0; j < nc; j++) | |
131 for (int i = 0; i < nr; i++) | |
132 { | |
133 double abs_a_elem = abs (a.elem (i, j)); | |
134 double abs_b_elem = abs (b.elem (i, j)); | |
135 if (abs_a_elem > abs_b_elem) | |
136 result.elem (i, j) = a.elem (i, j); | |
137 else | |
138 result.elem (i, j) = b.elem (i, j); | |
139 } | |
140 | |
141 return result; | |
142 } | |
143 | |
144 Octave_object | |
145 column_min (const Octave_object& args, int nargout) | |
146 { | |
147 Octave_object retval; | |
148 | |
149 tree_constant arg1; | |
150 tree_constant arg2; | |
151 tree_constant_rep::constant_type arg1_type = | |
152 tree_constant_rep::unknown_constant; | |
153 tree_constant_rep::constant_type arg2_type = | |
154 tree_constant_rep::unknown_constant; | |
155 | |
156 int nargin = args.length (); | |
157 | |
158 switch (nargin) | |
159 { | |
160 case 3: | |
161 arg2 = args(2).make_numeric (); | |
162 arg2_type = arg2.const_type (); | |
163 // Fall through... | |
164 case 2: | |
165 arg1 = args(1).make_numeric (); | |
166 arg1_type = arg1.const_type (); | |
167 break; | |
168 default: | |
169 panic_impossible (); | |
170 break; | |
171 } | |
172 | |
173 if (nargin == 2 && (nargout == 1 || nargout == 0)) | |
174 { | |
175 retval.resize (1); | |
176 switch (arg1_type) | |
177 { | |
178 case tree_constant_rep::scalar_constant: | |
179 retval(0) = arg1.double_value (); | |
180 break; | |
181 case tree_constant_rep::complex_scalar_constant: | |
182 retval(0) = arg1.complex_value (); | |
183 break; | |
184 case tree_constant_rep::matrix_constant: | |
185 { | |
186 Matrix m = arg1.matrix_value (); | |
187 if (m.rows () == 1) | |
188 retval(0) = m.row_min (); | |
189 else | |
190 retval(0) = tree_constant (m.column_min (), 0); | |
191 } | |
192 break; | |
193 case tree_constant_rep::complex_matrix_constant: | |
194 { | |
195 ComplexMatrix m = arg1.complex_matrix_value (); | |
196 if (m.rows () == 1) | |
197 retval(0) = m.row_min (); | |
198 else | |
199 retval(0) = tree_constant (m.column_min (), 0); | |
200 } | |
201 break; | |
202 default: | |
203 panic_impossible (); | |
204 break; | |
205 } | |
206 } | |
207 else if (nargin == 2 && nargout == 2) | |
208 { | |
209 retval.resize (2); | |
210 switch (arg1_type) | |
211 { | |
212 case tree_constant_rep::scalar_constant: | |
213 { | |
214 retval(0) = arg1.double_value (); | |
215 retval(1) = 1; | |
216 } | |
217 break; | |
218 case tree_constant_rep::complex_scalar_constant: | |
219 { | |
220 retval(0) = arg1.complex_value (); | |
221 retval(1) = 1; | |
222 } | |
223 break; | |
224 case tree_constant_rep::matrix_constant: | |
225 { | |
226 Matrix m = arg1.matrix_value (); | |
227 if (m.rows () == 1) | |
228 { | |
229 retval(0) = m.row_min (); | |
230 retval(1) = m.row_min_loc (); | |
231 } | |
232 else | |
233 { | |
234 retval(0) = tree_constant (m.column_min (), 0); | |
235 retval(1) = tree_constant (m.column_min_loc (), 0); | |
236 } | |
237 } | |
238 break; | |
239 case tree_constant_rep::complex_matrix_constant: | |
240 { | |
241 ComplexMatrix m = arg1.complex_matrix_value (); | |
242 if (m.rows () == 1) | |
243 { | |
244 retval(0) = m.row_min (); | |
245 retval(1) = m.row_min_loc (); | |
246 } | |
247 else | |
248 { | |
249 retval(0) = tree_constant (m.column_min (), 0); | |
250 retval(1) = tree_constant (m.column_min_loc (), 0); | |
251 } | |
252 } | |
253 break; | |
254 default: | |
255 panic_impossible (); | |
256 break; | |
257 } | |
258 } | |
259 else if (nargin == 3) | |
260 { | |
261 if (arg1.rows () == arg2.rows () | |
262 && arg1.columns () == arg2.columns ()) | |
263 { | |
264 retval.resize (1); | |
265 switch (arg1_type) | |
266 { | |
267 case tree_constant_rep::scalar_constant: | |
268 { | |
269 double result; | |
270 double a_elem = arg1.double_value (); | |
271 double b_elem = arg2.double_value (); | |
272 result = MIN (a_elem, b_elem); | |
273 retval(0) = result; | |
274 } | |
275 break; | |
276 case tree_constant_rep::complex_scalar_constant: | |
277 { | |
278 Complex result; | |
279 Complex a_elem = arg1.complex_value (); | |
280 Complex b_elem = arg2.complex_value (); | |
281 if (abs (a_elem) < abs (b_elem)) | |
282 result = a_elem; | |
283 else | |
284 result = b_elem; | |
285 retval(0) = result; | |
286 } | |
287 break; | |
288 case tree_constant_rep::matrix_constant: | |
289 { | |
290 Matrix result; | |
291 result = min (arg1.matrix_value (), arg2.matrix_value ()); | |
292 retval(0) = result; | |
293 } | |
294 break; | |
295 case tree_constant_rep::complex_matrix_constant: | |
296 { | |
297 ComplexMatrix result; | |
298 result = min (arg1.complex_matrix_value (), | |
299 arg2.complex_matrix_value ()); | |
300 retval(0) = result; | |
301 } | |
302 break; | |
303 default: | |
304 panic_impossible (); | |
305 break; | |
306 } | |
307 } | |
308 else | |
309 error ("min: nonconformant matrices"); | |
310 } | |
311 else | |
312 panic_impossible (); | |
313 | |
314 return retval; | |
315 } | |
316 | |
317 Octave_object | |
318 column_max (const Octave_object& args, int nargout) | |
319 { | |
320 Octave_object retval; | |
321 | |
322 tree_constant arg1; | |
323 tree_constant arg2; | |
324 tree_constant_rep::constant_type arg1_type = | |
325 tree_constant_rep::unknown_constant; | |
326 tree_constant_rep::constant_type arg2_type = | |
327 tree_constant_rep::unknown_constant; | |
328 | |
329 int nargin = args.length (); | |
330 | |
331 switch (nargin) | |
332 { | |
333 case 3: | |
334 arg2 = args(2).make_numeric (); | |
335 arg2_type = arg2.const_type (); | |
336 // Fall through... | |
337 case 2: | |
338 arg1 = args(1).make_numeric (); | |
339 arg1_type = arg1.const_type (); | |
340 break; | |
341 default: | |
342 panic_impossible (); | |
343 break; | |
344 } | |
345 | |
346 if (nargin == 2 && (nargout == 1 || nargout == 0)) | |
347 { | |
348 retval.resize (1); | |
349 switch (arg1_type) | |
350 { | |
351 case tree_constant_rep::scalar_constant: | |
352 retval(0) = arg1.double_value (); | |
353 break; | |
354 case tree_constant_rep::complex_scalar_constant: | |
355 retval(0) = arg1.complex_value (); | |
356 break; | |
357 case tree_constant_rep::matrix_constant: | |
358 { | |
359 Matrix m = arg1.matrix_value (); | |
360 if (m.rows () == 1) | |
361 retval(0) = m.row_max (); | |
362 else | |
363 retval(0) = tree_constant (m.column_max (), 0); | |
364 } | |
365 break; | |
366 case tree_constant_rep::complex_matrix_constant: | |
367 { | |
368 ComplexMatrix m = arg1.complex_matrix_value (); | |
369 if (m.rows () == 1) | |
370 retval(0) = m.row_max (); | |
371 else | |
372 retval(0) = tree_constant (m.column_max (), 0); | |
373 } | |
374 break; | |
375 default: | |
376 panic_impossible (); | |
377 break; | |
378 } | |
379 } | |
380 else if (nargin == 2 && nargout == 2) | |
381 { | |
382 retval.resize (2); | |
383 switch (arg1_type) | |
384 { | |
385 case tree_constant_rep::scalar_constant: | |
386 { | |
387 retval(0) = arg1.double_value (); | |
388 retval(1) = 1; | |
389 } | |
390 break; | |
391 case tree_constant_rep::complex_scalar_constant: | |
392 { | |
393 retval(0) = arg1.complex_value (); | |
394 retval(1) = 1; | |
395 } | |
396 break; | |
397 case tree_constant_rep::matrix_constant: | |
398 { | |
399 Matrix m = arg1.matrix_value (); | |
400 if (m.rows () == 1) | |
401 { | |
402 retval(0) = m.row_max (); | |
403 retval(1) = m.row_max_loc (); | |
404 } | |
405 else | |
406 { | |
407 retval(0) = tree_constant (m.column_max (), 0); | |
408 retval(1) = tree_constant (m.column_max_loc (), 0); | |
409 } | |
410 } | |
411 break; | |
412 case tree_constant_rep::complex_matrix_constant: | |
413 { | |
414 ComplexMatrix m = arg1.complex_matrix_value (); | |
415 if (m.rows () == 1) | |
416 { | |
417 retval(0) = m.row_max (); | |
418 retval(1) = m.row_max_loc (); | |
419 } | |
420 else | |
421 { | |
422 retval(0) = tree_constant (m.column_max (), 0); | |
423 retval(1) = tree_constant (m.column_max_loc (), 0); | |
424 } | |
425 } | |
426 break; | |
427 default: | |
428 panic_impossible (); | |
429 break; | |
430 } | |
431 } | |
432 else if (nargin == 3) | |
433 { | |
434 if (arg1.rows () == arg2.rows () | |
435 && arg1.columns () == arg2.columns ()) | |
436 { | |
437 retval.resize (1); | |
438 switch (arg1_type) | |
439 { | |
440 case tree_constant_rep::scalar_constant: | |
441 { | |
442 double result; | |
443 double a_elem = arg1.double_value (); | |
444 double b_elem = arg2.double_value (); | |
445 result = MAX (a_elem, b_elem); | |
446 retval(0) = result; | |
447 } | |
448 break; | |
449 case tree_constant_rep::complex_scalar_constant: | |
450 { | |
451 Complex result; | |
452 Complex a_elem = arg1.complex_value (); | |
453 Complex b_elem = arg2.complex_value (); | |
454 if (abs (a_elem) > abs (b_elem)) | |
455 result = a_elem; | |
456 else | |
457 result = b_elem; | |
458 retval(0) = result; | |
459 } | |
460 break; | |
461 case tree_constant_rep::matrix_constant: | |
462 { | |
463 Matrix result; | |
464 result = max (arg1.matrix_value (), arg2.matrix_value ()); | |
465 retval(0) = result; | |
466 } | |
467 break; | |
468 case tree_constant_rep::complex_matrix_constant: | |
469 { | |
470 ComplexMatrix result; | |
471 result = max (arg1.complex_matrix_value (), | |
472 arg2.complex_matrix_value ()); | |
473 retval(0) = result; | |
474 } | |
475 break; | |
476 default: | |
477 panic_impossible (); | |
478 break; | |
479 } | |
480 } | |
481 else | |
482 error ("max: nonconformant matrices"); | |
483 } | |
484 else | |
485 panic_impossible (); | |
486 | |
487 return retval; | |
488 } | |
489 | |
490 /* | |
491 ;;; Local Variables: *** | |
492 ;;; mode: C++ *** | |
493 ;;; page-delimiter: "^/\\*" *** | |
494 ;;; End: *** | |
495 */ |