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;