Mercurial > hg > octave-avbm
comparison src/data.cc @ 10538:26673015caec
extend hypot to accept >2 args
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 22 Apr 2010 09:41:37 +0200 |
parents | f094ac9bc93e |
children | 7b4ffe27bbb4 |
comparison
equal
deleted
inserted
replaced
10537:fdf28dae0f37 | 10538:26673015caec |
---|---|
280 %!error <Invalid call to atan2.*> atan2 (1, 2, 3); | 280 %!error <Invalid call to atan2.*> atan2 (1, 2, 3); |
281 | 281 |
282 */ | 282 */ |
283 | 283 |
284 | 284 |
285 static octave_value | |
286 do_hypot (const octave_value& x, const octave_value& y) | |
287 { | |
288 octave_value retval; | |
289 | |
290 octave_value arg0 = x, arg1 = y; | |
291 if (! arg0.is_numeric_type ()) | |
292 gripe_wrong_type_arg ("hypot", arg0); | |
293 else if (! arg1.is_numeric_type ()) | |
294 gripe_wrong_type_arg ("hypot", arg1); | |
295 else | |
296 { | |
297 if (arg0.is_complex_type ()) | |
298 arg0 = arg0.abs (); | |
299 if (arg1.is_complex_type ()) | |
300 arg1 = arg1.abs (); | |
301 | |
302 if (arg0.is_single_type () || arg1.is_single_type ()) | |
303 { | |
304 if (arg0.is_scalar_type () && arg1.is_scalar_type ()) | |
305 retval = hypotf (arg0.float_value (), arg1.float_value ()); | |
306 else | |
307 { | |
308 FloatNDArray a0 = arg0.float_array_value (); | |
309 FloatNDArray a1 = arg1.float_array_value (); | |
310 retval = binmap<float> (a0, a1, ::hypotf, "hypot"); | |
311 } | |
312 } | |
313 else | |
314 { | |
315 bool a0_scalar = arg0.is_scalar_type (); | |
316 bool a1_scalar = arg1.is_scalar_type (); | |
317 if (a0_scalar && a1_scalar) | |
318 retval = hypot (arg0.scalar_value (), arg1.scalar_value ()); | |
319 else if ((a0_scalar || arg0.is_sparse_type ()) | |
320 && (a1_scalar || arg1.is_sparse_type ())) | |
321 { | |
322 SparseMatrix m0 = arg0.sparse_matrix_value (); | |
323 SparseMatrix m1 = arg1.sparse_matrix_value (); | |
324 retval = binmap<double> (m0, m1, ::hypot, "hypot"); | |
325 } | |
326 else | |
327 { | |
328 NDArray a0 = arg0.array_value (); | |
329 NDArray a1 = arg1.array_value (); | |
330 retval = binmap<double> (a0, a1, ::hypot, "hypot"); | |
331 } | |
332 } | |
333 } | |
334 | |
335 return retval; | |
336 } | |
285 | 337 |
286 DEFUN (hypot, args, , | 338 DEFUN (hypot, args, , |
287 "-*- texinfo -*-\n\ | 339 "-*- texinfo -*-\n\ |
288 @deftypefn {Built-in Function} {} hypot (@var{x}, @var{y})\n\ | 340 @deftypefn {Built-in Function} {} hypot (@var{x}, @var{y})\n\ |
341 @deftypefnx {Built-in Function} {} hypot (@var{x}, @var{y}, @var{z}, ...)\n\ | |
289 Compute the element-by-element square root of the sum of the squares of\n\ | 342 Compute the element-by-element square root of the sum of the squares of\n\ |
290 @var{x} and @var{y}. This is equivalent to\n\ | 343 @var{x} and @var{y}. This is equivalent to\n\ |
291 @code{sqrt (@var{x}.^2 + @var{y}.^2)}, but calculated in a manner that\n\ | 344 @code{sqrt (@var{x}.^2 + @var{y}.^2)}, but calculated in a manner that\n\ |
292 avoids overflows for large values of @var{x} or @var{y}.\n\ | 345 avoids overflows for large values of @var{x} or @var{y}.\n\ |
346 @code{hypot} can also be called with more than 2 arguments; in this case,\n\ | |
347 the arguments are accumulated from left to right:\n\ | |
348 @example\n\ | |
349 hypot (hypot (@var{x}, @var{y}), @var{z})\n\ | |
350 hypot (hypot (hypot (@var{x}, @var{y}), @var{z}), @var{w}) etc.\n\ | |
351 @end example\n\ | |
293 @end deftypefn") | 352 @end deftypefn") |
294 { | 353 { |
295 octave_value retval; | 354 octave_value retval; |
296 | 355 |
297 int nargin = args.length (); | 356 int nargin = args.length (); |
298 | 357 |
299 if (nargin == 2) | 358 if (nargin == 2) |
300 { | 359 { |
301 octave_value arg0 = args(0), arg1 = args(1); | 360 retval = do_hypot (args(0), args(1)); |
302 if (! arg0.is_numeric_type ()) | 361 } |
303 gripe_wrong_type_arg ("hypot", arg0); | 362 else if (nargin >= 3) |
304 else if (! arg1.is_numeric_type ()) | 363 { |
305 gripe_wrong_type_arg ("hypot", arg1); | 364 retval = args(0); |
306 else | 365 for (int i = 1; i < nargin && ! error_state; i++) |
307 { | 366 retval = do_hypot (retval, args(i)); |
308 if (arg0.is_complex_type ()) | |
309 arg0 = arg0.abs (); | |
310 if (arg1.is_complex_type ()) | |
311 arg1 = arg1.abs (); | |
312 | |
313 if (arg0.is_single_type () || arg1.is_single_type ()) | |
314 { | |
315 if (arg0.is_scalar_type () && arg1.is_scalar_type ()) | |
316 retval = hypotf (arg0.float_value (), arg1.float_value ()); | |
317 else | |
318 { | |
319 FloatNDArray a0 = arg0.float_array_value (); | |
320 FloatNDArray a1 = arg1.float_array_value (); | |
321 retval = binmap<float> (a0, a1, ::hypotf, "hypot"); | |
322 } | |
323 } | |
324 else | |
325 { | |
326 bool a0_scalar = arg0.is_scalar_type (); | |
327 bool a1_scalar = arg1.is_scalar_type (); | |
328 if (a0_scalar && a1_scalar) | |
329 retval = hypot (arg0.scalar_value (), arg1.scalar_value ()); | |
330 else if ((a0_scalar || arg0.is_sparse_type ()) | |
331 && (a1_scalar || arg1.is_sparse_type ())) | |
332 { | |
333 SparseMatrix m0 = arg0.sparse_matrix_value (); | |
334 SparseMatrix m1 = arg1.sparse_matrix_value (); | |
335 retval = binmap<double> (m0, m1, ::hypot, "hypot"); | |
336 } | |
337 else | |
338 { | |
339 NDArray a0 = arg0.array_value (); | |
340 NDArray a1 = arg1.array_value (); | |
341 retval = binmap<double> (a0, a1, ::hypot, "hypot"); | |
342 } | |
343 } | |
344 } | |
345 } | 367 } |
346 else | 368 else |
347 print_usage (); | 369 print_usage (); |
348 | 370 |
349 return retval; | 371 return retval; |