Octave and Freemat

Ben Abbott bpabbott at mac.com
Wed Mar 5 07:03:07 CST 2008


On Mar 5, 2008, at 4:12 AM, David Bateman wrote:

> Ben Abbott wrote:
>>
>> On Mar 4, 2008, at 8:27 PM, Ben Abbott wrote:
>>
>>>
>>> On Mar 4, 2008, at 6:46 PM, Sebastien Loisel wrote:
>>>
>>>> Dear David,
>>>>
>>>> Thank you for your email.
>>>>
>>>> On Tue, Mar 4, 2008 at 5:44 PM, David Bateman
>>>> <David.Bateman at motorola.com> wrote:
>>>> f = find (p ./ max(p));
>>>> p = p (f(1):end);
>>>>
>>>> Are you missing an abs maybe? Also, I hope you did your checking  
>>>> for
>>>> nans and infs before you got there.
>>>>
>>>> -- 
>>>> Sébastien Loisel
>>>
>>>
>>> To respect Matlab an error should result when NaNs or Infs are  
>>> present.
>>>
>>> The abs shouldn't be necessary. In fact, if NaNs and Infs have
>>> already be handled, why not
>>>
>>> f = find (p);
>>> p = p(f(1):end);
>>> n = numel (p)-1;
>>> A = diag (ones (n-1, 1), -1);
>>> A(1,:) = -p(2:n+1) ./ p(1);
>>> z = eig (A);
>>>
>>> Ben
>>
>> ok, nix the simple solution.
>>
>> I checked Matlab, they apparently remove have some special handling  
>> of
>> trailing zeros.
>>
>>>> p = [poly([3 3 3 3]), 0 0 0 0];
>>
>>>> abs(roots(p)-[0; 0; 0; 0; 3; 3; 3; 3])
>>
>> ans =
>>
>>            0
>>            0
>>            0
>>            0
>>   0.00051228
>>   0.00051228
>>   0.00051223
>>   0.00051223
>>
>>>>
>>
>> What should be included is the check for Infs and NaNs. Beyond that  
>> we
>> might add some tests for consistency with Matlab.
>>
>> How about the attached?
>>
>>
>
> How about the attached instead that is a combination of what Sebastien
> pointed out and your fixes..
>
> D.
>
>
> -- 
> David Bateman                                 
> David.Bateman at motorola.com
> Motorola Labs - Paris                        +33 1 69 35 48 04 (Ph)
> Parc Les Algorithmes, Commune de St Aubin    +33 6 72 01 06 33 (Mob)
> 91193 Gif-Sur-Yvette FRANCE                  +33 1 69 35 77 01 (Fax)
>
> The information contained in this communication has been classified  
> as:
>
> [x] General Business Information
> [ ] Motorola Internal Use Only
> [ ] Motorola Confidential Proprietary
>
> # HG changeset patch
> # User Sebastien Loisel
> # Date 1204708216 -3600
> # Node ID 1dea613279ff9b360b5df72ed3779ca7fcb9f166
> # Parent  1ea3f5aa672f0bb1919a4355d38fee00690028c2
> Apply a scaling factor to leading zero removal in roots.m
>
> diff --git a/scripts/ChangeLog b/scripts/ChangeLog
> --- a/scripts/ChangeLog
> +++ b/scripts/ChangeLog
> @@ -1,3 +1,12 @@ 2008-03-04  Bill Denney  <bill at denney.ws
> +2008-03-05  Bill Denney  <bill at denney.ws>
> +
> +	* polynomial/roots.m: Modified to catch Infs and/or NaNs.
> +
> +2008-03-05  Sebastien Loisel  <loisel at temple.edu>
> +
> +	* polynomial/roots.m: Apply a scaling fator to the removal of the
> +	leading zeros.
> +
> 2008-03-04  Bill Denney  <bill at denney.ws>
>
> 	* geometry/rectint.m: New function.
> diff --git a/scripts/polynomial/roots.m b/scripts/polynomial/roots.m
> --- a/scripts/polynomial/roots.m
> +++ b/scripts/polynomial/roots.m
> @@ -83,16 +83,22 @@ function r = roots (v)
>
>   if (nargin != 1 || min (size (v)) > 1)
>     print_usage ();
> +  elseif (any (isnan(v) | isinf(v)))
> +    error ("roots: inputs must not contain Inf or NaN.")
>   endif
>
> -  n = length (v);
> -  v = reshape (v, 1, n);
> +  n = numel (v);
> +  v = v(:);
>
>   ## If v = [ 0 ... 0 v(k+1) ... v(k+l) 0 ... 0 ], we can remove the
>   ## leading k zeros and n - k - l roots of the polynomial are zero.
>
> -  f = find (v);
> -  m = max (size (f));
> +  if (isempty (v))
> +    f = v;
> +  else
> +    f = find (v ./ max (abs (v)));
> +  endif
> +  m = numel (f);
>
>   if (m > 0 && n > 1)
>     v = v(f(1):f(m));
> @@ -114,9 +120,24 @@ function r = roots (v)
>
> endfunction
>
> +%!test
> +%! p = [poly([3 3 3 3]), 0 0 0 0];
> +%! r = sort (roots (p));
> +%! assert (r, [0; 0; 0; 0; 3; 3; 3; 3], 0.001)
> +
> %!assert(all (all (abs (roots ([1, -6, 11, -6]) - [3; 2; 1]) < sqrt  
> (eps))));
>
> %!assert(isempty (roots ([])));
>
> %!error roots ([1, 2; 3, 4]);
> +
> +%!assert(isempty (roots (1)));
>
> + %!error roots ([1, 2; 3, 4]);
> +
> +%!error roots ([1 Inf 1]);
> +
> +%!error roots ([1 NaN 1]);
> +
> +%!assert(roots ([1e-200, -1e200, 1]), 1e-200)
> +%!assert(roots ([1e-200, -1e200 * 1i, 1]), -1e-200 * 1i)

Regarding this part,

> +  if (isempty (v))
> +    f = v;
> +  else
> +    f = find (v ./ max (abs (v)));
> +  endif
> +  m = numel (f);

It appears an error will result if v = 0. Which should return [].  
Perhaps something like that below?

   f = find (v);
   if (any (f))
     v = v ./ max (abs (v));
     f = find (v);
   endif
   m = numel (f);

The first test below tests this concern, and the second tests for a  
"special" features of Matlab's implementation, which apparently is  
consistent with the above since the check for Inf is done prior to  
"v ./ max (abs (v))".

%!assert(isempty (roots (0)));

%!assert(roots([realmin, realmax, realmax]), -1)

Ben


More information about the Octave-maintainers mailing list