bug 8488 : In min/max function, NaN values was propagated. 65/8565/2
Cedric Delamarre [Mon, 6 Aug 2012 13:35:54 +0000 (15:35 +0200)]
Change-Id: I238be678e57c7f38806421d12c3eb85c12543bff

scilab/CHANGES_5.4.X
scilab/modules/elementary_functions/sci_gateway/fortran/sci_f_maxi.f
scilab/modules/elementary_functions/tests/nonreg_tests/bug_8488.dia.ref [new file with mode: 0644]
scilab/modules/elementary_functions/tests/nonreg_tests/bug_8488.tst [new file with mode: 0644]

index 93c3d19..13e51ec 100644 (file)
@@ -29,6 +29,9 @@ Bug Fixes
 * Bug #8151 fixed - Under Mac OS X, item "Scilab/Quit Scilab" and "File/Quit" were
                     duplicates.
 
+* Bug #8488 fixed - NaN values was propagated when we performed the min/max between
+                    several matrices.
+
 * Bug #11411 fixed - save function used unsigned char to store length of string.
                      Now it is an integer.
 
index 9533702..6dddb41 100644 (file)
@@ -1,19 +1,19 @@
 c Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 c Copyright (C) INRIA
-c 
+c
 c This file must be used under the terms of the CeCILL.
 c This source file is licensed as described in the file COPYING, which
 c you should have received as part of this distribution.  The terms
-c are also available at    
+c are also available at
 c http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 c     -------------------------------
 c
       subroutine intmaxi(fname,id)
 c     -------------------------------
-c     maxi mini interface 
+c     maxi mini interface
 c     -------------------------------
       character*(*) fname
-c     Interface for maxi and mini 
+c     Interface for maxi and mini
       INCLUDE 'stack.h'
       integer id(nsiz)
       logical checklhs,cremat
@@ -30,20 +30,20 @@ c
       topk=top
       if (.not.checklhs(fname,1,2)) return
       itype=gettype(topk)
-c     ------list case 
+c     ------list case
       if(itype.eq.15) goto 200
-c     ------sparse case 
+c     ------sparse case
       if(itype.eq.5) then
          call ref2val
          fin=fin-6
          fun=27
 c        *call* spelm
-         return 
+         return
       endif
       if(itype.eq.10.and.rhs.eq.2) goto 10
 
       if(itype.ne.1) then
-c     ------call macro 
+c     ------call macro
          top=topk
          il=iadr(lstk(top))
          if(istk(il).lt.0) il=iadr(istk(il+1))
@@ -59,9 +59,9 @@ c     ------call macro
 
       if(rhs.gt.1.and.itype.ne.10) goto 100
 c=====maxi mini (A1)
-c     ------simple case one argument which is a matrix or vector 
+c     ------simple case one argument which is a matrix or vector
       sel=0
- 10   if(rhs.eq.2) then 
+ 10   if(rhs.eq.2) then
          call  getorient(topk,sel)
          if(err.gt.0) return
          top=top-1
@@ -87,8 +87,8 @@ c     ------simple case one argument which is a matrix or vector
       endif
       if(sel.eq.-1) sel=mtlbsel(istk(iadr(lstk(top))+1),2)
 
-      if (sel.eq.1) then 
-c     ------------max of each column of a 
+      if (sel.eq.1) then
+c     ------------max of each column of a
          if (.not.cremat(fname,topk,0,1,n,lr,lir)) return
          if (.not.cremat(fname,topk+1,0,1,n,lkr,lkir)) return
          if ((fin.eq.17) .or. (fin.eq.54)) then
@@ -107,12 +107,12 @@ c     .    max
  16         continue
          endif
          call copyobj(fname,topk,topk-rhs+1)
-         if (lhs.eq.2) then 
+         if (lhs.eq.2) then
             call copyobj(fname,topk+1,topk-rhs+2)
          endif
-         top=topk-rhs+lhs            
+         top=topk-rhs+lhs
 c     ---------max of each row of a
-      else if (sel.eq.2) then       
+      else if (sel.eq.2) then
          if (.not.cremat(fname,topk,0,m,1,lr,lir)) return
          if (.not.cremat(fname,topk+1,0,m,1,lkr,lkir)) return
          if(fin.eq.17) then
@@ -131,17 +131,17 @@ c     .    max
  26         continue
          endif
          call copyobj(fname,topk,topk-rhs+1)
-         if (lhs.eq.2) then 
+         if (lhs.eq.2) then
             call copyobj(fname,topk+1,topk-rhs+2)
          endif
-         top=topk-rhs+lhs            
-c     ----- general maxi or mini 
-      else 
+         top=topk-rhs+lhs
+c     ----- general maxi or mini
+      else
          if (rhs.eq.2) topk=top
 
          x1=stk(lr1)
          k=1
-         if ((fin.eq.17) .or. (fin.eq.54)) then 
+         if ((fin.eq.17) .or. (fin.eq.54)) then
 c     .     mini
             k=idmin(m*n,stk(lr1),1)
          else
@@ -149,20 +149,20 @@ c     .     maxi
             k=idmax(m*n,stk(lr1),1)
          endif
          x1=stk(lr1-1+k)
-C     return the max or min 
+C     return the max or min
          if (.not.cremat(fname,topk,0,1,1,l1,li1)) return
          stk(l1)=x1
-C     return indices of max or min ([k] for vectors  or [kl,kc] 
-c     for matrices 
-         if(lhs.eq.2) then 
+C     return indices of max or min ([k] for vectors  or [kl,kc]
+c     for matrices
+         if(lhs.eq.2) then
             top=topk+1
-            if(m.eq.1.or.n.eq.1) then 
+            if(m.eq.1.or.n.eq.1) then
                if (.not.cremat(fname,top,0,1,1,lr1,lc1)) return
                stk(lr1)=dble(k)
             else
                kc=k/m
                kl=k-kc*m
-               if(kl.eq.0) then 
+               if(kl.eq.0) then
                   kc=kc-1
                   kl=m
                endif
@@ -221,7 +221,7 @@ c     check argument and compute dimension of the result.
       if(.not.cremat(fname,topk+2,0,m,n,lind,lcw)) return
 c     maxi mini a plusieurs argument
       call dset(m*n,1.0d0,stk(lind),1)
-      test=getrmat(fname,topk,topk-rhs+1,mi,ni,lr1) 
+      test=getrmat(fname,topk,topk-rhs+1,mi,ni,lr1)
       if(mi*ni.eq.1) then
          call dset(m*n,stk(lr1),stk(lv),1)
       else
@@ -234,19 +234,19 @@ c     maxi mini a plusieurs argument
          else
             inc=1
          endif
-         if ((fin.eq.17) .or. (fin.eq.54)) then 
-c     mini            
+         if ((fin.eq.17) .or. (fin.eq.54)) then
+c     mini
             do 111 j=0,m*n-1
-               if (stk(lri).lt.stk(lv+j).or.isanan(stk(lri)).eq.1) then 
-                  stk(lv+j)= stk(lri) 
+               if (stk(lri).lt.stk(lv+j).or.isanan(stk(lv+j)).eq.1) then
+                  stk(lv+j)= stk(lri)
                   stk(lind+j)= dble(i)
                endif
                lri=lri+inc
  111         continue
          else
             do 112 j=0,m*n-1
-               if (stk(lri).gt.stk(lv+j).or.isanan(stk(lri)).eq.1) then 
-                  stk(lv+j)= stk(lri) 
+               if (stk(lri).gt.stk(lv+j).or.isanan(stk(lv+j)).eq.1) then
+                  stk(lv+j)= stk(lri)
                   stk(lind+j)= dble(i)
                endif
                lri=lri+inc
@@ -254,31 +254,31 @@ c     mini
          endif
  120   continue
       call copyobj(fname,topk+1,topk-rhs+1)
-      if (lhs.eq.2) then 
+      if (lhs.eq.2) then
          call copyobj(fname,topk+2,topk-rhs+2)
       endif
       top=topk-rhs+lhs
       return
 c
  200  continue
-c=====maxi mini of list arguments 
-      if(rhs.ne.1) then 
+c=====maxi mini of list arguments
+      if(rhs.ne.1) then
          buf = fname // ': only one argument if it is a list'
          call error(999)
          return
       endif
       if(.not.getilist(fname,topk,topk,n1,1,il1)) return
-      if(n1.eq.0) then 
+      if(n1.eq.0) then
          buf = fname // ': empty list '
          call error(999)
          return
       endif
       if(.not.getlistmat(fname,topk,topk,1,it1,m,n,lr1,lc1)
      $     ) return
-      if ( it1.ne.0) then 
+      if ( it1.ne.0) then
          buf = fname // 'arguments must be real '
          call error(999)
-         return 
+         return
       endif
       if(m*n.le.0) then
          err=1
@@ -287,25 +287,25 @@ c=====maxi mini of list arguments
       endif
       if(.not.cremat(fname,topk+1,0,m,n,lrw,lcw)) return
       if(.not.cremat(fname,topk+2,0,m,n,lrkw,lckw)) return
-      call dset(m*n,1.0d0,stk(lrkw),1)           
+      call dset(m*n,1.0d0,stk(lrkw),1)
       call unsfdcopy(m*n,stk(lr1),1,stk(lrw),1)
-c     test si n1 > 1 
-      if ( n1.gt.1) then 
+c     test si n1 > 1
+      if ( n1.gt.1) then
          do 215 i=2,n1
             if(.not.getlistmat(fname,topk,topk,i,iti,mi,ni,
      $           lri,lci))           return
-            if ( iti.ne.0) then 
+            if ( iti.ne.0) then
                buf = fname // 'arguments must be real '
                call error(999)
-               return 
+               return
             endif
             if(.not.checkval(fname,m,mi)) return
             if(.not.checkval(fname,n,ni)) return
-            if ((fin.eq.17) .or. (fin.eq.54)) then 
-c     mini            
+            if ((fin.eq.17) .or. (fin.eq.54)) then
+c     mini
                do 211 j=0,m*n-1
                   x1=stk(lri+j)
-                  if (x1.lt.stk(lrw+j).or.isanan(x1).eq.1) then 
+                  if (x1.lt.stk(lrw+j).or.isanan(lrw+j).eq.1) then
                      stk(lrw+j)=x1
                      stk(lrkw+j)= i
                   endif
@@ -313,7 +313,7 @@ c     mini
             else
                do 212 j=0,m*n-1
                   x1=stk(lri+j)
-                  if (x1.gt.stk(lrw+j).or.isanan(x1).eq.1) then 
+                  if (x1.gt.stk(lrw+j).or.isanan(lrw+j).eq.1) then
                      stk(lrw+j)=x1
                      stk(lrkw+j)= i
                   endif
@@ -322,11 +322,11 @@ c     mini
  215     continue
       endif
       call copyobj(fname,topk+1,topk)
-      if (lhs.eq.2) then 
+      if (lhs.eq.2) then
          call copyobj(fname,topk+2,topk+1)
       endif
       top=topk-rhs+lhs
-c=====end of list case 
+c=====end of list case
       return
       end
 c     -------------------------------
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8488.dia.ref b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8488.dia.ref
new file mode 100644 (file)
index 0000000..bd0da66
--- /dev/null
@@ -0,0 +1,34 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- JVM NOT MANDATORY -->
+// <-- Non-regression test for bug 8488 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=8488
+//
+// <-- Short Description -->
+// The min and max function inconsistently propagate NaN inputs
+// min
+assert_checkfalse(isnan(min([1 %nan])));
+assert_checkfalse(isnan(min([%nan 1])));
+assert_checktrue(isnan(min([%nan %nan])));
+A = rand(3,3);
+A(2) = %nan;
+B = rand(3,3);
+B(6) = %nan;
+M = min(A, B);
+assert_checkfalse(isnan(M));
+// max
+assert_checkfalse(isnan(max([1 %nan])));
+assert_checkfalse(isnan(max([%nan 1])));
+assert_checktrue(isnan(max([%nan %nan])));
+A = rand(3,3);
+A(2) = %nan;
+B = rand(3,3);
+B(6) = %nan;
+M = max(A, B);
+assert_checkfalse(isnan(M));
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8488.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8488.tst
new file mode 100644 (file)
index 0000000..58b9e50
--- /dev/null
@@ -0,0 +1,46 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- JVM NOT MANDATORY -->
+
+// <-- Non-regression test for bug 8488 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=8488
+//
+// <-- Short Description -->
+// The min and max function inconsistently propagate NaN inputs
+
+// min
+assert_checkfalse(isnan(min([1 %nan])));
+assert_checkfalse(isnan(min([%nan 1])));
+assert_checktrue(isnan(min([%nan %nan])));
+
+A = rand(3,3);
+A(2) = %nan;
+
+B = rand(3,3);
+B(6) = %nan;
+
+M = min(A, B);
+
+assert_checkfalse(isnan(M));
+
+// max
+assert_checkfalse(isnan(max([1 %nan])));
+assert_checkfalse(isnan(max([%nan 1])));
+assert_checktrue(isnan(max([%nan %nan])));
+
+A = rand(3,3);
+A(2) = %nan;
+
+B = rand(3,3);
+B(6) = %nan;
+
+M = max(A, B);
+
+assert_checkfalse(isnan(M));