[Numpy-svn] r5264 - in trunk/numpy/ma: . tests

numpy-svn@scip... numpy-svn@scip...
Sun Jun 8 18:04:51 CDT 2008


Author: pierregm
Date: 2008-06-08 18:04:42 -0500 (Sun, 08 Jun 2008)
New Revision: 5264

Modified:
   trunk/numpy/ma/core.py
   trunk/numpy/ma/mrecords.py
   trunk/numpy/ma/tests/test_core.py
   trunk/numpy/ma/tests/test_extras.py
   trunk/numpy/ma/tests/test_mrecords.py
Log:
CHANGES:
core:
* When creating a masked array with named fields, the mask has now a flexible type [(n,bool) for n in fields], which allows individual fields to be masked.
* When a masked array has named fields, setting the mask to a sequence of booleans will set the mask of all the fields of the corresponding record.
* A new property, recordmask, returns either the mask (when no named fields) or a boolean array where values are True if all the fields of one record are masked, False otherwise.
* A new private attribute, _isfield, has been introduced to keep track whether an array is a field of a record-like masked array or not, and make sure that the mask is properly propagated.
* Setting an existing mask to nomask will only fill the mask with False, not transform it to nomask

mrecords:
* _fieldmask is now only a synonym for _mask, kept for convenience
* revamped __getattribute__ to the example of numpy.core.records.recarray.__getattribute__
* __setslice__ and filled are now inhertied from MaskedArray

tests
* The tests in test_core have been reorganized to improve clarity and avoid duplication.
* test_extras now uses the convention "import numpy as np"



Modified: trunk/numpy/ma/core.py
===================================================================
--- trunk/numpy/ma/core.py	2008-06-08 18:10:55 UTC (rev 5263)
+++ trunk/numpy/ma/core.py	2008-06-08 23:04:42 UTC (rev 5264)
@@ -1196,7 +1196,7 @@
                           DeprecationWarning)
             shrink = flag
         # Process data............
-        _data = narray(data, dtype=dtype, copy=copy, subok=True, ndmin=ndmin)
+        _data = np.array(data, dtype=dtype, copy=copy, subok=True, ndmin=ndmin)
         _baseclass = getattr(data, '_baseclass', type(_data))
         _basedict = getattr(data, '_basedict', getattr(data, '__dict__', {}))
         if not isinstance(data, MaskedArray) or not subok:
@@ -1207,7 +1207,15 @@
         if hasattr(data,'_mask') and not isinstance(data, ndarray):
             _data._mask = data._mask
             _sharedmask = True
-        # Process mask ...........
+        # Process mask ...............................
+        # Number of named fields (or zero if none)
+        names_ = _data.dtype.names or ()
+        # Type of the mask
+        if names_:
+            mdtype = [(n, MaskType) for n in names_]
+        else:
+            mdtype = MaskType
+        # Case 1. : no mask in input ............
         if mask is nomask:
              # Erase the current mask ?
             if not keep_mask:
@@ -1216,7 +1224,7 @@
                     _data._mask = nomask
                 # With full version
                 else:
-                    _data._mask = np.zeros(_data.shape, dtype=MaskType)
+                    _data._mask = np.zeros(_data.shape, dtype=mdtype)
             if copy:
                 _data._mask = _data._mask.copy()
                 _data._sharedmask = False
@@ -1224,7 +1232,14 @@
                 _data._sharedmask = True
         # Case 2. : With a mask in input ........
         else:
-            mask = np.array(mask, dtype=MaskType, copy=copy)
+            # Read the mask with the current mdtype
+            try:
+                mask = np.array(mask, copy=copy, dtype=mdtype)
+            # Or assume it's a sequence of bool/int
+            except TypeError:
+                mask = np.array([tuple([m]*len(mdtype)) for m in mask],
+                                 dtype=mdtype)
+            # Make sure the mask and the data have the same shape
             if mask.shape != _data.shape:
                 (nd, nm) = (_data.size, mask.size)
                 if nm == 1:
@@ -1245,7 +1260,11 @@
                     _data._mask = mask
                     _data._sharedmask = not copy
                 else:
-                    _data._mask = umath.logical_or(mask, _data._mask)
+                    if names_:
+                        for n in names_:
+                            _data._mask[n] |= mask[n]
+                    else:
+                        _data._mask = np.logical_or(mask, _data._mask)
                     _data._sharedmask = False
         # Update fill_value.......
         if fill_value is None:
@@ -1270,6 +1289,7 @@
         _dict = dict(_fill_value=getattr(obj, '_fill_value', None),
                      _hardmask=getattr(obj, '_hardmask', False),
                      _sharedmask=getattr(obj, '_sharedmask', False),
+                     _isfield=getattr(obj, '_isfield', False),
                      _baseclass=getattr(obj,'_baseclass', _baseclass),
                      _basedict=_basedict,)
         self.__dict__.update(_dict)
@@ -1379,12 +1399,11 @@
             if isinstance(indx, basestring):
                 if self._fill_value is not None:
                     dout._fill_value = self._fill_value[indx]
+                dout._isfield = True
             # Update the mask if needed
             if _mask is not nomask:
-                if isinstance(indx, basestring):
-                    dout._mask = _mask.reshape(dout.shape)
-                else:
-                    dout._mask = ndarray.__getitem__(_mask, indx).reshape(dout.shape)
+                dout._mask = _mask[indx]
+                dout._sharedmask = True
 #               Note: Don't try to check for m.any(), that'll take too long...
         return dout
     #........................
@@ -1402,47 +1421,64 @@
 #            msg = "Masked arrays must be filled before they can be used as indices!"
 #            raise IndexError, msg
         if isinstance(indx, basestring):
-            ndarray.__setitem__(self._data, indx, getdata(value))
-            warnings.warn("MaskedArray.__setitem__ on fields: "\
-                          "The mask is NOT affected!")
+            ndarray.__setitem__(self._data, indx, value)
+            ndarray.__setitem__(self._mask, indx, getmask(value))
             return
-        #....
+        #........................................
+#        ndgetattr = ndarray.__getattribute__
+        _names = ndarray.__getattribute__(self,'dtype').names or ()
+        _data = self._data
+        _mask = ndarray.__getattribute__(self,'_mask')
+        #........................................
         if value is masked:
-            m = self._mask
-            if m is nomask:
-                m = np.zeros(self.shape, dtype=MaskType)
-            m[indx] = True
-            self._mask = m
-            self._sharedmask = False
+            # The mask wasn't set: create a full version...
+            if _mask is nomask:
+                _mask = self._mask = make_mask_none(self.shape, _names)
+            # Now, set the mask to its value.
+            if _names:
+                _mask[indx] = tuple([True,] * len(_names))
+            else:
+                _mask[indx] = True
+            if not self._isfield:
+                self._sharedmask = False
             return
-        #....
-#        dval = np.array(value, copy=False, dtype=self.dtype)
+        #........................................
+        # Get the _data part of the new value
         dval = value
-        mval = getmask(value)
-        if self._mask is nomask:
+        # Get the _mask part of the new value
+        mval = getattr(value, '_mask', nomask)
+        if _names and mval is nomask:
+            mval = tuple([False] * len(_names))
+        if _mask is nomask:
             # Set the data, then the mask
-            ndarray.__setitem__(self._data,indx,dval)
+            ndarray.__setitem__(_data, indx, dval)
             if mval is not nomask:
-                self._mask = np.zeros(self.shape, dtype=MaskType)
-                self._mask[indx] = mval
+                _mask = self._mask = make_mask_none(self.shape, _names)
+                ndarray.__setitem__(_mask, indx, mval)
         elif not self._hardmask:
             # Unshare the mask if necessary to avoid propagation
-            self.unshare_mask()
+            if not self._isfield:
+                self.unshare_mask()
+                _mask = ndarray.__getattribute__(self,'_mask')
             # Set the data, then the mask
-            ndarray.__setitem__(self._data, indx, dval)
-            ndarray.__setitem__(self._mask, indx, mval)
-        elif hasattr(indx, 'dtype') and (indx.dtype==bool_):
-            indx = indx * umath.logical_not(self._mask)
-            ndarray.__setitem__(self._data, indx, dval)
+            ndarray.__setitem__(_data, indx, dval)
+            ndarray.__setitem__(_mask, indx, mval)
+        elif hasattr(indx, 'dtype') and (indx.dtype==MaskType):
+            indx = indx * umath.logical_not(_mask)
+            ndarray.__setitem__(_data,indx,dval)
         else:
-            mindx = mask_or(self._mask[indx], mval, copy=True)
+            if _names:
+                err_msg = "Flexible 'hard' masks are not yet supported..."
+                raise NotImplementedError(err_msg)
+            mindx = mask_or(_mask[indx], mval, copy=True)
             dindx = self._data[indx]
             if dindx.size > 1:
                 dindx[~mindx] = dval
             elif mindx is nomask:
                 dindx = dval
-            ndarray.__setitem__(self._data, indx, dindx)
-            self._mask[indx] = mindx
+            ndarray.__setitem__(_data, indx, dindx)
+            _mask[indx] = mindx
+        return
     #............................................
     def __getslice__(self, i, j):
         """x.__getslice__(i, j) <==> x[i:j]
@@ -1466,28 +1502,57 @@
         """Set the mask.
 
         """
-        if mask is not nomask:
-            mask = narray(mask, copy=copy, dtype=MaskType)
-            # We could try to check whether shrinking is needed..
-            # ... but we would waste some precious time
-#            if self._shrinkmask and not mask.any():
-#                mask = nomask
-        if self._mask is nomask:
-            self._mask = mask
-        elif self._hardmask:
-            if mask is not nomask:
-                self._mask.__ior__(mask)
-        else:
-            # This one is tricky: if we set the mask that way, we may break the
-            # propagation. But if we don't, we end up with a mask full of False
-            # and a test on nomask fails...
+        names = ndarray.__getattribute__(self,'dtype').names
+        current_mask = ndarray.__getattribute__(self,'_mask')
+        if mask is masked:
+            mask = True
+        # Make sure the mask is set
+        if (current_mask is nomask):
+            # Just don't do anything is there's nothing to do...
             if mask is nomask:
-                self._mask = nomask
+                return
+            current_mask = self._mask = make_mask_none(self.shape, names)
+        # No named fields.........
+        if names is None:
+            # Hardmask: don't unmask the data
+            if self._hardmask:
+                current_mask |= mask
+            # Softmask: set everything to False
             else:
-                self.unshare_mask()
-                self._mask.flat = mask
-        if self._mask.shape:
-            self._mask = np.reshape(self._mask, self.shape)
+                current_mask.flat = mask
+        # Named fields w/ ............
+        else:
+            mdtype = current_mask.dtype
+            mask = np.array(mask, copy=False)
+            # Mask is a singleton
+            if not mask.ndim:
+                # It's a boolean : make a record
+                if mask.dtype.kind == 'b':
+                    mask = np.array(tuple([mask.item()]*len(mdtype)),
+                                    dtype=mdtype)
+                # It's a record: make sure the dtype is correct
+                else:
+                    mask = mask.astype(mdtype)
+            # Mask is a sequence
+            else:
+                # Make sure the new mask is a ndarray with the proper dtype
+                try:
+                    mask = np.array(mask, copy=copy, dtype=mdtype)
+                # Or assume it's a sequence of bool/int
+                except TypeError:
+                    mask = np.array([tuple([m]*len(mdtype)) for m in mask],
+                                    dtype=mdtype)
+            # Hardmask: don't unmask the data
+            if self._hardmask:
+                for n in names:
+                    current_mask[n] |= mask[n]
+            # Softmask: set everything to False
+            else:
+                current_mask.flat = mask
+        # Reshape if needed
+        if current_mask.shape:
+            current_mask.shape = self.shape
+        return
     _set_mask = __setmask__
     #....
     def _get_mask(self):
@@ -1498,6 +1563,26 @@
 #        return self._mask.reshape(self.shape)
         return self._mask
     mask = property(fget=_get_mask, fset=__setmask__, doc="Mask")
+    #
+    def _getrecordmask(self):
+        """Return the mask of the records.
+    A record is masked when all the fields are masked.
+
+        """
+        if self.dtype.names is None:
+            return self._mask
+        elif self.size > 1:
+            return self._mask.view((bool_, len(self.dtype))).all(1)
+        else:
+            return self._mask.view((bool_, len(self.dtype))).all()
+    
+    def _setrecordmask(self):
+        """Return the mask of the records.
+    A record is masked when all the fields are masked.
+
+        """
+        raise NotImplementedError("Coming soon: setting the mask per records!")
+    recordmask = property(fget=_getrecordmask)
     #............................................
     def harden_mask(self):
         """Force the mask to hard.
@@ -1602,14 +1687,22 @@
 
         """
         m = self._mask
-        if m is nomask or not m.any():
+        if m is nomask:
             return self._data
         #
         if fill_value is None:
             fill_value = self.fill_value
         #
         if self is masked_singleton:
-            result = np.asanyarray(fill_value)
+            return np.asanyarray(fill_value)
+        #
+        if len(self.dtype):
+            result = self._data.copy()
+            for n in result.dtype.names:
+                field = result[n]
+                np.putmask(field, self._mask[n], self.fill_value[n])
+        elif not m.any():
+            return self._data
         else:
             result = self._data.copy()
             try:
@@ -1682,11 +1775,14 @@
                     else:
                         return str(self._data)
                 # convert to object array to make filled work
-#!!!: the two lines below seem more robust than the self._data.astype
-#                res = numeric.empty(self._data.shape, object_)
-#                numeric.putmask(res,~m,self._data)
-                res = self._data.astype("|O8")
-                res[m] = f
+                names = self.dtype.names
+                if names is None:
+                    res = self._data.astype("|O8")
+                    res[m] = f
+                else:
+                    res = self._data.astype([(n,'|O8') for n in names])
+                    for field in names:
+                        np.putmask(res[field], m[field], f)
         else:
             res = self.filled(self.fill_value)
         return str(res)
@@ -3399,7 +3495,7 @@
     if getmask(a) is nomask:
         if valmask is not nomask:
             a._sharedmask = True
-            a.mask = np.zeros(a.shape, dtype=bool_)
+            a._mask = make_mask_none(a.shape, a.dtype.names)
             np.putmask(a._mask, mask, valmask)
     elif a._hardmask:
         if valmask is not nomask:

Modified: trunk/numpy/ma/mrecords.py
===================================================================
--- trunk/numpy/ma/mrecords.py	2008-06-08 18:10:55 UTC (rev 5263)
+++ trunk/numpy/ma/mrecords.py	2008-06-08 23:04:42 UTC (rev 5264)
@@ -72,7 +72,7 @@
         elif isinstance(names, str):
             new_names = names.split(',')
         else:
-            raise NameError, "illegal input names %s" % `names`
+            raise NameError("illegal input names %s" % `names`)
         nnames = len(new_names)
         if nnames < ndescr:
             new_names += default_names[nnames:]
@@ -85,7 +85,7 @@
                 ndescr.append(t)
         else:
             ndescr.append((n,t[1]))
-    return numeric.dtype(ndescr)
+    return np.dtype(ndescr)
 
 
 def _get_fieldmask(self):
@@ -125,7 +125,7 @@
         mdtype = [(k,'|b1') for (k,_) in self.dtype.descr]
         if mask is nomask or not np.size(mask):
             if not keep_mask:
-                self._fieldmask = tuple([False]*len(mdtype))
+                self._mask = tuple([False]*len(mdtype))
         else:
             mask = np.array(mask, copy=copy)
             if mask.shape != self.shape:
@@ -144,79 +144,40 @@
                 self._sharedmask = True
             else:
                 if mask.dtype == mdtype:
-                    _fieldmask = mask
+                    _mask = mask
                 else:
-                    _fieldmask = np.array([tuple([m]*len(mdtype)) for m in mask],
-                                          dtype=mdtype)
-                self._fieldmask = _fieldmask
+                    _mask = np.array([tuple([m]*len(mdtype)) for m in mask],
+                                     dtype=mdtype)
+                self._mask = _mask
         return self
     #......................................................
     def __array_finalize__(self,obj):
+        MaskedArray._update_from(self,obj)
         # Make sure we have a _fieldmask by default ..
         _fieldmask = getattr(obj, '_fieldmask', None)
         if _fieldmask is None:
             mdescr = [(n,'|b1') for (n,_) in self.dtype.descr]
-            _mask = getattr(obj, '_mask', nomask)
-            if _mask is nomask:
-                _fieldmask = np.empty(self.shape, dtype=mdescr).view(recarray)
-                _fieldmask.flat = tuple([False]*len(mdescr))
+            objmask = getattr(obj, '_mask', nomask)
+            if objmask is nomask:
+                _mask = np.empty(self.shape, dtype=mdescr).view(recarray)
+                _mask.flat = tuple([False]*len(mdescr))
             else:
-                _fieldmask = narray([tuple([m]*len(mdescr)) for m in _mask],
-                                    dtype=mdescr).view(recarray)
-        # Update some of the attributes
-        if obj is not None:
-            _baseclass = getattr(obj,'_baseclass',type(obj))
+                _mask = narray([tuple([m]*len(mdescr)) for m in objmask],
+                               dtype=mdescr).view(recarray)
         else:
-            _baseclass = recarray
-        attrdict = dict(_fieldmask=_fieldmask,
-                        _hardmask=getattr(obj,'_hardmask',False),
-                        _fill_value=getattr(obj,'_fill_value',None),
-                        _sharedmask=getattr(obj,'_sharedmask',False),
-                        _baseclass=_baseclass)
-        self.__dict__.update(attrdict)
-        # Finalize as a regular maskedarray .....
-        # Update special attributes ...
-        self._basedict = getattr(obj, '_basedict', getattr(obj,'__dict__',{}))
-        self.__dict__.update(self._basedict)
+            _mask = _fieldmask
+        # Update some of the attributes
+        _locdict = self.__dict__
+        if _locdict['_baseclass'] == ndarray:
+            _locdict['_baseclass'] = recarray
+        _locdict.update(_mask=_mask, _fieldmask=_mask)
         return
-    #......................................................
+
     def _getdata(self):
         "Returns the data as a recarray."
         return ndarray.view(self,recarray)
     _data = property(fget=_getdata)
-    #......................................................
-    def __setmask__(self, mask):
-        "Sets the mask and update the fieldmask."
-        names = self.dtype.names
-        fmask = self.__dict__['_fieldmask']
-        #
-        if isinstance(mask,ndarray) and mask.dtype.names == names:
-            for n in names:
-                fmask[n] = mask[n].astype(bool)
-#            self.__dict__['_fieldmask'] = fmask.view(recarray)
-            return
-        newmask = make_mask(mask, copy=False)
-        if names is not None:
-            if self._hardmask:
-                for n in names:
-                    fmask[n].__ior__(newmask)
-            else:
-                for n in names:
-                    fmask[n].flat = newmask
-        return
-    _setmask = __setmask__
-    #
-    def _getmask(self):
-        """Return the mask of the mrecord.
-    A record is masked when all the fields are masked.
 
-        """
-        if self.size > 1:
-            return self._fieldmask.view((bool_, len(self.dtype))).all(1)
-        else:
-            return self._fieldmask.view((bool_, len(self.dtype))).all()
-    mask = _mask = property(fget=_getmask, fset=_setmask)
-    #......................................................
     def __len__(self):
         "Returns the length"
         # We have more than one record
@@ -224,88 +185,104 @@
             return len(self._data)
         # We have only one record: return the nb of fields
         return len(self.dtype)
-    #......................................................
+
     def __getattribute__(self, attr):
-        "Returns the given attribute."
         try:
-            # Returns a generic attribute
-            return object.__getattribute__(self,attr)
-        except AttributeError:
-            # OK, so attr must be a field name
+            return object.__getattribute__(self, attr)
+        except AttributeError: # attr must be a fieldname
             pass
-        # Get the list of fields ......
-        _names = self.dtype.names
-        if attr in _names:
-            _data = self._data
-            _mask = self._fieldmask
-#            obj = masked_array(_data.__getattribute__(attr), copy=False,
-#                               mask=_mask.__getattribute__(attr))
-            # Use a view in order to avoid the copy of the mask in MaskedArray.__new__
-            obj = narray(_data.__getattribute__(attr), copy=False).view(MaskedArray)
-            obj._mask = _mask.__getattribute__(attr)
-            if not obj.ndim and obj._mask:
-                return masked
-            return obj
-        raise AttributeError,"No attribute '%s' !" % attr
+        fielddict = ndarray.__getattribute__(self,'dtype').fields
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError, "record array has no attribute %s" % attr
+        # So far, so good...
+        _localdict = ndarray.__getattribute__(self,'__dict__')
+        _data = ndarray.view(self, _localdict['_baseclass'])
+        obj = _data.getfield(*res)
+        if obj.dtype.fields:
+            raise NotImplementedError("MaskedRecords is currently limited to"\
+                                      "simple records...")
+        obj = obj.view(MaskedArray)
+        obj._baseclass = ndarray
+        obj._isfield = True
+        # Get some special attributes
+        _fill_value = _localdict.get('_fill_value', None)
+        _mask = _localdict.get('_mask', None)
+        # Reset the object's mask
+        if _mask is not None:
+            try:
+                obj._mask = _mask[attr]
+            except IndexError:
+                # Couldn't find a mask: use the default (nomask)
+                pass
+        # Reset the field values
+        if _fill_value is not None:
+            try:
+                obj._fill_value = _fill_value[attr]
+            except ValueError:
+                obj._fill_value = None
+        return obj
 
+
     def __setattr__(self, attr, val):
         "Sets the attribute attr to the value val."
-#        newattr = attr not in self.__dict__
+        # Should we call __setmask__ first ?
+        if attr in ['_mask','mask','_fieldmask','fieldmask']:
+            self.__setmask__(val)
+            return
+        # Create a shortcut (so that we don't have to call getattr all the time) 
+        _localdict = self.__dict__
+        # Check whether we're creating a new field
+        newattr = attr not in _localdict
         try:
             # Is attr a generic attribute ?
             ret = object.__setattr__(self, attr, val)
         except:
             # Not a generic attribute: exit if it's not a valid field
-            fielddict = self.dtype.names or {}
+            fielddict = ndarray.__getattribute__(self,'dtype').fields or {}
             if attr not in fielddict:
                 exctype, value = sys.exc_info()[:2]
                 raise exctype, value
         else:
-            if attr in ['_mask','fieldmask']:
-                self.__setmask__(val)
-                return
             # Get the list of names ......
-            _names = self.dtype.names
-            if _names is None:
-                _names = []
-            else:
-                _names = list(_names)
+            fielddict = ndarray.__getattribute__(self,'dtype').fields or {}
             # Check the attribute
-            self_dict = self.__dict__
-            if attr not in _names+list(self_dict):
+#####            _localdict = self.__dict__
+            if attr not in fielddict:
                 return ret
-            if attr not in self_dict:         # We just added this one
+            if newattr:         # We just added this one
                 try:            #  or this setattr worked on an internal
                                 #  attribute.
                     object.__delattr__(self, attr)
                 except:
                     return ret
-        # Case #1.: Basic field ............
-        base_fmask = self._fieldmask
-        _names = self.dtype.names or []
-        _localdict = self.__dict__
-        if attr in _names:
-            if val is masked:
-                _fill_value = _localdict['_fill_value']
-                if _fill_value is not None:
-                    fval = _fill_value[attr]
-                else:
-                    fval = None
-                mval = True
+        # Let's try to set the field
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError,KeyError):
+            raise AttributeError, "record array has no attribute %s" % attr
+        # 
+        if val is masked:
+            _fill_value = _localdict['_fill_value']
+            if _fill_value is not None:
+                dval = _localdict['_fill_value'][attr]
             else:
-                fval = filled(val)
-                mval = getmaskarray(val)
-            if self._hardmask:
-                mval = mask_or(mval, base_fmask.__getattr__(attr))
-            self._data.__setattr__(attr, fval)
-            base_fmask.__setattr__(attr, mval)
-            return
-    #............................................
+                dval = val
+            mval = True
+        else:
+            dval = filled(val)
+            mval = getmaskarray(val)
+        obj = ndarray.__getattribute__(self,'_data').setfield(dval, *res)
+        _localdict['_mask'].__setitem__(attr, mval)
+        return obj
+
+
     def __getitem__(self, indx):
         """Returns all the fields sharing the same fieldname base.
 The fieldname base is either `_data` or `_mask`."""
         _localdict = self.__dict__
-        _fieldmask = _localdict['_fieldmask']
+        _mask = _localdict['_fieldmask']
         _data = self._data
         # We want a field ........
         if isinstance(indx, basestring):
@@ -314,7 +291,7 @@
             #!!!: ...that break propagation
             #!!!: Don't force the mask to nomask, that wrecks easy masking
             obj = _data[indx].view(MaskedArray)
-            obj._mask = _fieldmask[indx]
+            obj._mask = _mask[indx]
             obj._sharedmask = True
             fval = _localdict['_fill_value']
             if fval is not None:
@@ -325,47 +302,17 @@
             return obj
         # We want some elements ..
         # First, the data ........
-        obj = narray(_data[indx], copy=False).view(mrecarray)
-        obj._fieldmask = narray(_fieldmask[indx], copy=False).view(recarray)
+        obj = np.array(_data[indx], copy=False).view(mrecarray)
+        obj._mask = np.array(_mask[indx], copy=False).view(recarray)
         return obj
     #....
     def __setitem__(self, indx, value):
         "Sets the given record to value."
         MaskedArray.__setitem__(self, indx, value)
         if isinstance(indx, basestring):
-            self._fieldmask[indx] = ma.getmaskarray(value)
+            self._mask[indx] = ma.getmaskarray(value)
 
-    #............................................
-    def __setslice__(self, i, j, value):
-        "Sets the slice described by [i,j] to `value`."
-        _localdict = self.__dict__
-        d = self._data
-        m = _localdict['_fieldmask']
-        names = self.dtype.names
-        if value is masked:
-            for n in names:
-                m[i:j][n] = True
-        elif not self._hardmask:
-            fval = filled(value)
-            mval = getmaskarray(value)
-            for n in names:
-                d[n][i:j] = fval
-                m[n][i:j] = mval
-        else:
-            mindx = getmaskarray(self)[i:j]
-            dval = np.asarray(value)
-            valmask = getmask(value)
-            if valmask is nomask:
-                for n in names:
-                    mval = mask_or(m[n][i:j], valmask)
-                    d[n][i:j][~mval] = value
-            elif valmask.size > 1:
-                for n in names:
-                    mval = mask_or(m[n][i:j], valmask)
-                    d[n][i:j][~mval] = dval[~mval]
-                    m[n][i:j] = mask_or(m[n][i:j], mval)
-        self._fieldmask = m
-    #......................................................
+
     def __str__(self):
         "Calculates the string representation."
         if self.size > 1:
@@ -394,55 +341,25 @@
                 return ndarray.view(self, obj)
         except TypeError:
             pass
-        dtype = np.dtype(obj)
-        if dtype.fields is None:
-            return self.__array__().view(dtype)
+        dtype_ = np.dtype(obj)
+        if dtype_.fields is None:
+            return self.__array__().view(dtype_)
         return ndarray.view(self, obj)
-    #......................................................
-    def filled(self, fill_value=None):
-        """Returns an array of the same class as the _data part, where masked
-    values are filled with fill_value.
-    If fill_value is None, self.fill_value is used instead.
 
-    Subclassing is preserved.
-
-        """
-        _localdict = self.__dict__
-        d = self._data
-        fm = _localdict['_fieldmask']
-        if not np.asarray(fm, dtype=bool_).any():
-            return d
-        #
-        if fill_value is None:
-            value = _check_fill_value(_localdict['_fill_value'], d.dtype)
-        else:
-            value = fill_value
-            if np.size(value) == 1:
-                value = np.array(tuple([value,] * len(d.dtype)),
-                                 dtype=d.dtype)
-        #
-        if self is masked:
-            result = np.asanyarray(value)
-        else:
-            result = d.copy()
-            for n in d.dtype.names:
-                np.putmask(np.asarray(result[n]), np.asarray(fm[n]), value[n])
-        return result
-    #......................................................
     def harden_mask(self):
         "Forces the mask to hard"
         self._hardmask = True
     def soften_mask(self):
         "Forces the mask to soft"
         self._hardmask = False
-    #......................................................
+
     def copy(self):
         """Returns a copy of the masked record."""
         _localdict = self.__dict__
         copied = self._data.copy().view(type(self))
         copied._fieldmask = self._fieldmask.copy()
         return copied
-    #......................................................
+
     def tolist(self, fill_value=None):
         """Copy the data portion of the array to a hierarchical python
         list and returns that list.
@@ -638,10 +555,10 @@
     # Start the conversion loop .......
     for f in arr:
         try:
-            val = int(f)
+            int(f)
         except ValueError:
             try:
-                val = float(f)
+                float(f)
             except ValueError:
                 try:
                     val = complex(f)

Modified: trunk/numpy/ma/tests/test_core.py
===================================================================
--- trunk/numpy/ma/tests/test_core.py	2008-06-08 18:10:55 UTC (rev 5263)
+++ trunk/numpy/ma/tests/test_core.py	2008-06-08 23:04:42 UTC (rev 5264)
@@ -1,4 +1,4 @@
-# pylint: disable-msg=W0611, W0612, W0614, W0511,R0201
+# pylint: disable-msg=W0401,W0511,W0611,W0612,W0614,R0201,E1102
 """Tests suite for MaskedArray & subclassing.
 
 :author: Pierre Gerard-Marchant
@@ -9,47 +9,77 @@
 import types
 import warnings
 
-import numpy
+import numpy as np
 import numpy.core.fromnumeric  as fromnumeric
+from numpy import ndarray
+
+
 from numpy.testing import NumpyTest, NumpyTestCase
 from numpy.testing import set_local_path, restore_path
 from numpy.testing.utils import build_err_msg
-from numpy import array as narray
 
 import numpy.ma.testutils
-from numpy.ma.testutils import *
+from numpy.ma.testutils import NumpyTestCase, \
+    assert_equal, assert_array_equal, fail_if_equal, assert_not_equal, \
+    assert_almost_equal, assert_mask_equal, assert_equal_records
 
 import numpy.ma.core as coremodule
 from numpy.ma.core import *
 
-pi = numpy.pi
+pi = np.pi
 
 set_local_path()
 from test_old_ma import *
 restore_path()
 
 #..............................................................................
-class TestMA(NumpyTestCase):
+class TestMaskedArray(NumpyTestCase):
     "Base test class for MaskedArrays."
+
     def __init__(self, *args, **kwds):
         NumpyTestCase.__init__(self, *args, **kwds)
         self.setUp()
 
     def setUp (self):
         "Base data definition."
-        x = narray([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
-        y = narray([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
         a10 = 10.
         m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
         m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1]
         xm = masked_array(x, mask=m1)
         ym = masked_array(y, mask=m2)
-        z = narray([-.5, 0., .5, .8])
+        z = np.array([-.5, 0., .5, .8])
         zm = masked_array(z, mask=[0,1,0,0])
-        xf = numpy.where(m1, 1.e+20, x)
+        xf = np.where(m1, 1.e+20, x)
         xm.set_fill_value(1.e+20)
         self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf)
-    #........................
+
+
+    def test_basicattributes(self):
+        "Tests some basic array attributes."
+        a = array([1,3,2])
+        b = array([1,3,2], mask=[1,0,1])
+        assert_equal(a.ndim, 1)
+        assert_equal(b.ndim, 1)
+        assert_equal(a.size, 3)
+        assert_equal(b.size, 3)
+        assert_equal(a.shape, (3,))
+        assert_equal(b.shape, (3,))
+
+
+    def test_basic0d(self):
+        "Checks masking a scalar"
+        x = masked_array(0)
+        assert_equal(str(x), '0')
+        x = masked_array(0,mask=True)
+        assert_equal(str(x), str(masked_print_option))
+        x = masked_array(0, mask=False)
+        assert_equal(str(x), '0')
+        x = array(0, mask=1)
+        assert(x.filled().dtype is x.data.dtype)
+
+
     def test_basic1d(self):
         "Test of basic array creation and properties in 1 dimension."
         (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
@@ -58,7 +88,7 @@
         assert((xm-ym).filled(0).any())
         fail_if_equal(xm.mask.astype(int_), ym.mask.astype(int_))
         s = x.shape
-        assert_equal(numpy.shape(xm), s)
+        assert_equal(np.shape(xm), s)
         assert_equal(xm.shape, s)
         assert_equal(xm.dtype, x.dtype)
         assert_equal(zm.dtype, z.dtype)
@@ -67,7 +97,8 @@
         assert_array_equal(xm, xf)
         assert_array_equal(filled(xm, 1.e20), xf)
         assert_array_equal(x, xm)
-    #........................
+
+
     def test_basic2d(self):
         "Test of basic array creation and properties in 2 dimensions."
         (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
@@ -77,7 +108,7 @@
             xm.shape = s
             ym.shape = s
             xf.shape = s
-
+            #
             assert(not isMaskedArray(x))
             assert(isMaskedArray(xm))
             assert_equal(shape(xm), s)
@@ -87,308 +118,27 @@
             assert_equal(xm, xf)
             assert_equal(filled(xm, 1.e20), xf)
             assert_equal(x, xm)
-    #........................
-    def test_basic_arithmetic (self):
-        "Test of basic arithmetic."
-        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        a2d = array([[1,2],[0,4]])
-        a2dm = masked_array(a2d, [[0,0],[1,0]])
-        assert_equal(a2d * a2d, a2d * a2dm)
-        assert_equal(a2d + a2d, a2d + a2dm)
-        assert_equal(a2d - a2d, a2d - a2dm)
-        for s in [(12,), (4,3), (2,6)]:
-            x = x.reshape(s)
-            y = y.reshape(s)
-            xm = xm.reshape(s)
-            ym = ym.reshape(s)
-            xf = xf.reshape(s)
-            assert_equal(-x, -xm)
-            assert_equal(x + y, xm + ym)
-            assert_equal(x - y, xm - ym)
-            assert_equal(x * y, xm * ym)
-            assert_equal(x / y, xm / ym)
-            assert_equal(a10 + y, a10 + ym)
-            assert_equal(a10 - y, a10 - ym)
-            assert_equal(a10 * y, a10 * ym)
-            assert_equal(a10 / y, a10 / ym)
-            assert_equal(x + a10, xm + a10)
-            assert_equal(x - a10, xm - a10)
-            assert_equal(x * a10, xm * a10)
-            assert_equal(x / a10, xm / a10)
-            assert_equal(x**2, xm**2)
-            assert_equal(abs(x)**2.5, abs(xm) **2.5)
-            assert_equal(x**y, xm**ym)
-            assert_equal(numpy.add(x,y), add(xm, ym))
-            assert_equal(numpy.subtract(x,y), subtract(xm, ym))
-            assert_equal(numpy.multiply(x,y), multiply(xm, ym))
-            assert_equal(numpy.divide(x,y), divide(xm, ym))
-    #........................
-    def test_mixed_arithmetic(self):
-        "Tests mixed arithmetics."
-        na = narray([1])
-        ma = array([1])
-        self.failUnless(isinstance(na + ma, MaskedArray))
-        self.failUnless(isinstance(ma + na, MaskedArray))
-    #........................
-    def test_inplace_arithmetic(self):
-        """Test of inplace operations and rich comparisons"""
-        # addition
-        x = arange(10)
-        y = arange(10)
-        xm = arange(10)
-        xm[2] = masked
-        x += 1
-        assert_equal(x, y+1)
-        xm += 1
-        assert_equal(xm, y+1)
-        # subtraction
-        x = arange(10)
-        xm = arange(10)
-        xm[2] = masked
-        x -= 1
-        assert_equal(x, y-1)
-        xm -= 1
-        assert_equal(xm, y-1)
-        # multiplication
-        x = arange(10)*1.0
-        xm = arange(10)*1.0
-        xm[2] = masked
-        x *= 2.0
-        assert_equal(x, y*2)
-        xm *= 2.0
-        assert_equal(xm, y*2)
-        # division
-        x = arange(10)*2
-        xm = arange(10)*2
-        xm[2] = masked
-        x /= 2
-        assert_equal(x, y)
-        xm /= 2
-        assert_equal(xm, y)
-        # division, pt 2
-        x = arange(10)*1.0
-        xm = arange(10)*1.0
-        xm[2] = masked
-        x /= 2.0
-        assert_equal(x, y/2.0)
-        xm /= arange(10)
-        assert_equal(xm, ones((10,)))
 
-        warnings.simplefilter('ignore', DeprecationWarning)
-        x = arange(10).astype(float_)
-        xm = arange(10)
-        xm[2] = masked
-        id1 = x.raw_data().ctypes.data
-        x += 1.
-        assert (id1 == x.raw_data().ctypes.data)
-        assert_equal(x, y+1.)
-        warnings.simplefilter('default', DeprecationWarning)
-
-        # addition w/ array
-        x = arange(10, dtype=float_)
-        xm = arange(10, dtype=float_)
-        xm[2] = masked
-        m = xm.mask
-        a = arange(10, dtype=float_)
-        a[-1] = masked
-        x += a
-        xm += a
-        assert_equal(x,y+a)
-        assert_equal(xm,y+a)
-        assert_equal(xm.mask, mask_or(m,a.mask))
-        # subtraction w/ array
-        x = arange(10, dtype=float_)
-        xm = arange(10, dtype=float_)
-        xm[2] = masked
-        m = xm.mask
-        a = arange(10, dtype=float_)
-        a[-1] = masked
-        x -= a
-        xm -= a
-        assert_equal(x,y-a)
-        assert_equal(xm,y-a)
-        assert_equal(xm.mask, mask_or(m,a.mask))
-        # multiplication w/ array
-        x = arange(10, dtype=float_)
-        xm = arange(10, dtype=float_)
-        xm[2] = masked
-        m = xm.mask
-        a = arange(10, dtype=float_)
-        a[-1] = masked
-        x *= a
-        xm *= a
-        assert_equal(x,y*a)
-        assert_equal(xm,y*a)
-        assert_equal(xm.mask, mask_or(m,a.mask))
-        # division w/ array
-        x = arange(10, dtype=float_)
-        xm = arange(10, dtype=float_)
-        xm[2] = masked
-        m = xm.mask
-        a = arange(10, dtype=float_)
-        a[-1] = masked
-        x /= a
-        xm /= a
-        assert_equal(x,y/a)
-        assert_equal(xm,y/a)
-        assert_equal(xm.mask, mask_or(mask_or(m,a.mask), (a==0)))
-        #
+    def test_concatenate_basic(self):
+        "Tests concatenations."
         (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        z = xm/ym
-        assert_equal(z._mask, [1,1,1,0,0,1,1,0,0,0,1,1])
-        assert_equal(z._data, [0.2,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.])
-        xm = xm.copy()
-        xm /= ym
-        assert_equal(xm._mask, [1,1,1,0,0,1,1,0,0,0,1,1])
-        assert_equal(xm._data, [1/5.,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.])
+        # basic concatenation
+        assert_equal(np.concatenate((x,y)), concatenate((xm,ym)))
+        assert_equal(np.concatenate((x,y)), concatenate((x,y)))
+        assert_equal(np.concatenate((x,y)), concatenate((xm,y)))
+        assert_equal(np.concatenate((x,y,x)), concatenate((x,ym,x)))
 
-    def test_inplace_arithmetixx(self):
-        tiny = numpy.finfo(float).tiny
-        a = array([tiny, 1./tiny, 0.])
-        assert_equal(getmaskarray(a/2), [0,0,0])
-        assert_equal(getmaskarray(2/a), [1,0,1])
-
-    #..........................
-    def test_scalararithmetic(self):
-        "Tests some scalar arithmetics on MaskedArrays."
-        xm = array(0, mask=1)
-        assert((1/array(0)).mask)
-        assert((1 + xm).mask)
-        assert((-xm).mask)
-        assert((-xm).mask)
-        assert(maximum(xm, xm).mask)
-        assert(minimum(xm, xm).mask)
-        assert(xm.filled().dtype is xm.data.dtype)
-        x = array(0, mask=0)
-        assert_equal(x.filled().ctypes.data, x.ctypes.data)
-        assert_equal(str(xm), str(masked_print_option))
-        # Make sure we don't lose the shape in some circumstances
-        xm = array((0,0))/0.
-        assert_equal(xm.shape,(2,))
-        assert_equal(xm.mask,[1,1])
-    #.........................
-    def test_basic_ufuncs (self):
-        "Test various functions such as sin, cos."
-        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        assert_equal(numpy.cos(x), cos(xm))
-        assert_equal(numpy.cosh(x), cosh(xm))
-        assert_equal(numpy.sin(x), sin(xm))
-        assert_equal(numpy.sinh(x), sinh(xm))
-        assert_equal(numpy.tan(x), tan(xm))
-        assert_equal(numpy.tanh(x), tanh(xm))
-        assert_equal(numpy.sqrt(abs(x)), sqrt(xm))
-        assert_equal(numpy.log(abs(x)), log(xm))
-        assert_equal(numpy.log10(abs(x)), log10(xm))
-        assert_equal(numpy.exp(x), exp(xm))
-        assert_equal(numpy.arcsin(z), arcsin(zm))
-        assert_equal(numpy.arccos(z), arccos(zm))
-        assert_equal(numpy.arctan(z), arctan(zm))
-        assert_equal(numpy.arctan2(x, y), arctan2(xm, ym))
-        assert_equal(numpy.absolute(x), absolute(xm))
-        assert_equal(numpy.equal(x,y), equal(xm, ym))
-        assert_equal(numpy.not_equal(x,y), not_equal(xm, ym))
-        assert_equal(numpy.less(x,y), less(xm, ym))
-        assert_equal(numpy.greater(x,y), greater(xm, ym))
-        assert_equal(numpy.less_equal(x,y), less_equal(xm, ym))
-        assert_equal(numpy.greater_equal(x,y), greater_equal(xm, ym))
-        assert_equal(numpy.conjugate(x), conjugate(xm))
-    #........................
-    def test_count_func (self):
-        "Tests count"
-        ott = array([0.,1.,2.,3.], mask=[1,0,0,0])
-        assert( isinstance(count(ott), int))
-        assert_equal(3, count(ott))
-        assert_equal(1, count(1))
-        assert_equal(0, array(1,mask=[1]))
-        ott = ott.reshape((2,2))
-        assert isinstance(count(ott,0), ndarray)
-        assert isinstance(count(ott), types.IntType)
-        assert_equal(3, count(ott))
-        assert getmask(count(ott,0)) is nomask
-        assert_equal([1,2],count(ott,0))
-    #........................
-    def test_minmax_func (self):
-        "Tests minimum and maximum."
-        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        xr = numpy.ravel(x) #max doesn't work if shaped
-        xmr = ravel(xm)
-        assert_equal(max(xr), maximum(xmr)) #true because of careful selection of data
-        assert_equal(min(xr), minimum(xmr)) #true because of careful selection of data
-        #
-        assert_equal(minimum([1,2,3],[4,0,9]), [1,0,3])
-        assert_equal(maximum([1,2,3],[4,0,9]), [4,2,9])
-        x = arange(5)
-        y = arange(5) - 2
-        x[3] = masked
-        y[0] = masked
-        assert_equal(minimum(x,y), where(less(x,y), x, y))
-        assert_equal(maximum(x,y), where(greater(x,y), x, y))
-        assert minimum(x) == 0
-        assert maximum(x) == 4
-        #
-        x = arange(4).reshape(2,2)
-        x[-1,-1] = masked
-        assert_equal(maximum(x), 2)
-
-    def test_minmax_methods(self):
-        "Additional tests on max/min"
-        (_, _, _, _, _, xm, _, _, _, _) = self.d
-        xm.shape = (xm.size,)
-        assert_equal(xm.max(), 10)
-        assert(xm[0].max() is masked)
-        assert(xm[0].max(0) is masked)
-        assert(xm[0].max(-1) is masked)
-        assert_equal(xm.min(), -10.)
-        assert(xm[0].min() is masked)
-        assert(xm[0].min(0) is masked)
-        assert(xm[0].min(-1) is masked)
-        assert_equal(xm.ptp(), 20.)
-        assert(xm[0].ptp() is masked)
-        assert(xm[0].ptp(0) is masked)
-        assert(xm[0].ptp(-1) is masked)
-        #
-        x = array([1,2,3], mask=True)
-        assert(x.min() is masked)
-        assert(x.max() is masked)
-        assert(x.ptp() is masked)
-    #........................
-    def test_addsumprod (self):
-        "Tests add, sum, product."
-        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        assert_equal(numpy.add.reduce(x), add.reduce(x))
-        assert_equal(numpy.add.accumulate(x), add.accumulate(x))
-        assert_equal(4, sum(array(4),axis=0))
-        assert_equal(4, sum(array(4), axis=0))
-        assert_equal(numpy.sum(x,axis=0), sum(x,axis=0))
-        assert_equal(numpy.sum(filled(xm,0),axis=0), sum(xm,axis=0))
-        assert_equal(numpy.sum(x,0), sum(x,0))
-        assert_equal(numpy.product(x,axis=0), product(x,axis=0))
-        assert_equal(numpy.product(x,0), product(x,0))
-        assert_equal(numpy.product(filled(xm,1),axis=0), product(xm,axis=0))
-        s = (3,4)
-        x.shape = y.shape = xm.shape = ym.shape = s
-        if len(s) > 1:
-            assert_equal(numpy.concatenate((x,y),1), concatenate((xm,ym),1))
-            assert_equal(numpy.add.reduce(x,1), add.reduce(x,1))
-            assert_equal(numpy.sum(x,1), sum(x,1))
-            assert_equal(numpy.product(x,1), product(x,1))
-    #.........................
-    def test_concat(self):
+    def test_concatenate_alongaxis(self):
         "Tests concatenations."
         (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        # basic concatenation
-        assert_equal(numpy.concatenate((x,y)), concatenate((xm,ym)))
-        assert_equal(numpy.concatenate((x,y)), concatenate((x,y)))
-        assert_equal(numpy.concatenate((x,y)), concatenate((xm,y)))
-        assert_equal(numpy.concatenate((x,y,x)), concatenate((x,ym,x)))
         # Concatenation along an axis
         s = (3,4)
         x.shape = y.shape = xm.shape = ym.shape = s
-        assert_equal(xm.mask, numpy.reshape(m1, s))
-        assert_equal(ym.mask, numpy.reshape(m2, s))
+        assert_equal(xm.mask, np.reshape(m1, s))
+        assert_equal(ym.mask, np.reshape(m2, s))
         xmym = concatenate((xm,ym),1)
-        assert_equal(numpy.concatenate((x,y),1), xmym)
-        assert_equal(numpy.concatenate((xm.mask,ym.mask),1), xmym._mask)
+        assert_equal(np.concatenate((x,y),1), xmym)
+        assert_equal(np.concatenate((xm.mask,ym.mask),1), xmym._mask)
         #
         x=zeros(2)
         y=array(ones(2),mask=[False,True])
@@ -399,16 +149,75 @@
         assert_array_equal(z,[1,1,0,0])
         assert_array_equal(z.mask,[False,True,False,False])
 
-    #........................
+    def test_creation_ndmin(self):
+        "Check the use of ndmin"
+        x = array([1,2,3],mask=[1,0,0], ndmin=2)
+        assert_equal(x.shape,(1,3))
+        assert_equal(x._data,[[1,2,3]])
+        assert_equal(x._mask,[[1,0,0]])
+
+    def test_creation_maskcreation(self):
+        "Tests how masks are initialized at the creation of Maskedarrays."
+        data = arange(24, dtype=float_)
+        data[[3,6,15]] = masked
+        dma_1 = MaskedArray(data)
+        assert_equal(dma_1.mask, data.mask)
+        dma_2 = MaskedArray(dma_1)
+        assert_equal(dma_2.mask, dma_1.mask)
+        dma_3 = MaskedArray(dma_1, mask=[1,0,0,0]*6)
+        fail_if_equal(dma_3.mask, dma_1.mask)
+
+    def test_asarray(self):
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        xm.fill_value = -9999
+        xmm = asarray(xm)
+        assert_equal(xmm._data, xm._data)
+        assert_equal(xmm._mask, xm._mask)
+        assert_equal(xmm.fill_value, xm.fill_value)
+
+    def test_fix_invalid(self):
+        "Checks fix_invalid."
+        data = masked_array(np.sqrt([-1., 0., 1.]), mask=[0,0,1])
+        data_fixed = fix_invalid(data)
+        assert_equal(data_fixed._data, [data.fill_value, 0., 1.])
+        assert_equal(data_fixed._mask, [1., 0., 1.])
+
+    def test_maskedelement(self):
+        "Test of masked element"
+        x = arange(6)
+        x[1] = masked
+        assert(str(masked) ==  '--')
+        assert(x[1] is masked)
+        assert_equal(filled(x[1], 0), 0)
+        # don't know why these should raise an exception...
+        #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, masked)
+        #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, 2)
+        #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, xx)
+        #self.failUnlessRaises(Exception, lambda x,y: x+y, xx, masked)
+
+    def test_set_element_as_object(self):
+        """Tests setting elements with object""" 
+        a = empty(1,dtype=object)
+        x = (1,2,3,4,5)
+        a[0] = x
+        assert_equal(a[0], x)
+        assert(a[0] is x)
+        #
+        import datetime
+        dt = datetime.datetime.now()
+        a[0] = dt
+        assert(a[0] is dt)
+
+
     def test_indexing(self):
         "Tests conversions and indexing"
-        x1 = numpy.array([1,2,4,3])
+        x1 = np.array([1,2,4,3])
         x2 = array(x1, mask=[1,0,0,0])
         x3 = array(x1, mask=[0,1,0,1])
         x4 = array(x1)
     # test conversion to strings
         junk, garbage = str(x2), repr(x2)
-        assert_equal(numpy.sort(x1),sort(x2,endwith=False))
+        assert_equal(np.sort(x1),sort(x2,endwith=False))
     # tests of indexing
         assert type(x2[1]) is type(x1[1])
         assert x1[1] == x2[1]
@@ -435,21 +244,22 @@
         x4[:] = masked_array([1,2,3,4],[0,1,1,0])
         assert allequal(getmask(x4), array([0,1,1,0]))
         assert allequal(x4, array([1,2,3,4]))
-        x1 = numpy.arange(5)*1.0
+        x1 = np.arange(5)*1.0
         x2 = masked_values(x1, 3.0)
         assert_equal(x1,x2)
         assert allequal(array([0,0,0,1,0],MaskType), x2.mask)
 #FIXME: Well, eh, fill_value is now a property        assert_equal(3.0, x2.fill_value())
         assert_equal(3.0, x2.fill_value)
         x1 = array([1,'hello',2,3],object)
-        x2 = numpy.array([1,'hello',2,3],object)
+        x2 = np.array([1,'hello',2,3],object)
         s1 = x1[1]
         s2 = x2[1]
         assert_equal(type(s2), str)
         assert_equal(type(s1), str)
         assert_equal(s1, s2)
         assert x1[1:1].shape == (0,)
-    #........................
+
+
     def test_copy(self):
         "Tests of some subtle points of copying and sizing."
         n = [0,0,1,0,0]
@@ -460,7 +270,7 @@
         assert(m is not m3)
 
         warnings.simplefilter('ignore', DeprecationWarning)
-        x1 = numpy.arange(5)
+        x1 = np.arange(5)
         y1 = array(x1, mask=m)
         #assert( y1._data is x1)
         assert_equal(y1._data.__array_interface__, x1.__array_interface__)
@@ -515,48 +325,56 @@
         y = masked_array(x, copy=True)
         assert_not_equal(y._data.ctypes.data, x._data.ctypes.data)
         assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data)
-    #........................
-    def test_where(self):
-        "Test the where function"
-        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        d = where(xm>2,xm,-9)
-        assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.])
-        assert_equal(d._mask, xm._mask)
-        d = where(xm>2,-9,ym)
-        assert_equal(d, [5.,0.,3., 2., -1.,-9.,-9., -10., -9., 1., 0., -9.])
-        assert_equal(d._mask, [1,0,1,0,0,0,1,0,0,0,0,0])
-        d = where(xm>2, xm, masked)
-        assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.])
-        tmp = xm._mask.copy()
-        tmp[(xm<=2).filled(True)] = True
-        assert_equal(d._mask, tmp)
+
+
+    def test_pickling(self):
+        "Tests pickling"
+        import cPickle
+        a = arange(10)
+        a[::3] = masked
+        a.fill_value = 999
+        a_pickled = cPickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled._data, a._data)
+        assert_equal(a_pickled.fill_value, 999)
         #
-        ixm = xm.astype(int_)
-        d = where(ixm>2, ixm, masked)
-        assert_equal(d, [-9,-9,-9,-9, -9, 4, -9, -9, 10, -9, -9, 3])
-        assert_equal(d.dtype, ixm.dtype)
+        a = array(np.matrix(range(10)), mask=[1,0,1,0,0]*2)
+        a_pickled = cPickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled, a)
+        assert(isinstance(a_pickled._data,np.matrix))
+
+
+    def test_single_element_subscript(self):
+        "Tests single element subscripts of Maskedarrays."
+        a = array([1,3,2])
+        b = array([1,3,2], mask=[1,0,1])
+        assert_equal(a[0].shape, ())
+        assert_equal(b[0].shape, ())
+        assert_equal(b[1].shape, ())
+
+
+    def test_topython(self):
+        "Tests some communication issues with Python."
+        assert_equal(1, int(array(1)))
+        assert_equal(1.0, float(array(1)))
+        assert_equal(1, int(array([[[1]]])))
+        assert_equal(1.0, float(array([[1]])))
+        self.assertRaises(TypeError, float, array([1,1]))
         #
-        x = arange(10)
-        x[3] = masked
-        c = x >= 8
-        z = where(c , x, masked)
-        assert z.dtype is x.dtype
-        assert z[3] is masked
-        assert z[4] is masked
-        assert z[7] is masked
-        assert z[8] is not masked
-        assert z[9] is not masked
-        assert_equal(x,z)
+        warnings.simplefilter('ignore',UserWarning)
+        assert np.isnan(float(array([1],mask=[1])))
+        warnings.simplefilter('default',UserWarning)
         #
-        z = where(c , masked, x)
-        assert z.dtype is x.dtype
-        assert z[3] is masked
-        assert z[4] is not masked
-        assert z[7] is not masked
-        assert z[8] is masked
-        assert z[9] is masked
+        a = array([1,2,3],mask=[1,0,0])
+        self.assertRaises(TypeError, lambda:float(a))
+        assert_equal(float(a[-1]), 3.)
+        assert(np.isnan(float(a[0])))
+        self.assertRaises(TypeError, int, a)
+        assert_equal(int(a[-1]), 3)
+        self.assertRaises(MAError, lambda:int(a[0]))
 
-    #........................
+
     def test_oddfeatures_1(self):
         "Test of other odd features"
         x = arange(20)
@@ -568,7 +386,7 @@
         assert_equal(z.imag, 10*x)
         assert_equal((z*conjugate(z)).real, 101*x*x)
         z.imag[...] = 0.0
-
+        #
         x = arange(10)
         x[3] = masked
         assert str(x[3]) == str(masked)
@@ -584,8 +402,8 @@
         assert z[8] is masked
         assert z[9] is masked
         assert_equal(x,z)
-        #
-    #........................
+
+
     def test_oddfeatures_2(self):
         "Tests some more features."
         x = array([1.,2.,3.,4.,5.])
@@ -600,22 +418,8 @@
         assert z[1] is not masked
         assert z[2] is masked
         #
-        x = arange(6)
-        x[5] = masked
-        y = arange(6)*10
-        y[2] = masked
-        c = array([1,1,1,0,0,0], mask=[1,0,0,0,0,0])
-        cm = c.filled(1)
-        z = where(c,x,y)
-        zm = where(cm,x,y)
-        assert_equal(z, zm)
-        assert getmask(zm) is nomask
-        assert_equal(zm, [0,1,2,30,40,50])
-        z = where(c, masked, 1)
-        assert_equal(z, [99,99,99,1,1,1])
-        z = where(c, 1, masked)
-        assert_equal(z, [99, 1, 1, 99, 99, 99])
-    #........................
+
+
     def test_oddfeatures_3(self):
         """Tests some generic features."""
         atest = array([10], mask=True)
@@ -624,57 +428,251 @@
         atest[idx] = btest[idx]
         assert_equal(atest,[20])
     #........................
-    def test_oddfeatures_4(self):
-        """Tests some generic features."""
-        atest = ones((10,10,10), dtype=float_)
-        btest = zeros(atest.shape, MaskType)
-        ctest = masked_where(btest,atest)
-        assert_equal(atest,ctest)
-    #........................
-    def test_set_oddities(self):
-        """Tests setting elements with object""" 
-        a = empty(1,dtype=object)
-        x = (1,2,3,4,5)
-        a[0] = x
-        assert_equal(a[0], x)
-        assert(a[0] is x)
+
+#------------------------------------------------------------------------------
+
+class TestMaskedArrayArithmetic(NumpyTestCase):
+    "Base test class for MaskedArrays."
+
+    def setUp (self):
+        "Base data definition."
+        x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0,1,0,0])
+        xf = np.where(m1, 1.e+20, x)
+        xm.set_fill_value(1.e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf)
+
+
+    def test_basic_arithmetic (self):
+        "Test of basic arithmetic."
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        a2d = array([[1,2],[0,4]])
+        a2dm = masked_array(a2d, [[0,0],[1,0]])
+        assert_equal(a2d * a2d, a2d * a2dm)
+        assert_equal(a2d + a2d, a2d + a2dm)
+        assert_equal(a2d - a2d, a2d - a2dm)
+        for s in [(12,), (4,3), (2,6)]:
+            x = x.reshape(s)
+            y = y.reshape(s)
+            xm = xm.reshape(s)
+            ym = ym.reshape(s)
+            xf = xf.reshape(s)
+            assert_equal(-x, -xm)
+            assert_equal(x + y, xm + ym)
+            assert_equal(x - y, xm - ym)
+            assert_equal(x * y, xm * ym)
+            assert_equal(x / y, xm / ym)
+            assert_equal(a10 + y, a10 + ym)
+            assert_equal(a10 - y, a10 - ym)
+            assert_equal(a10 * y, a10 * ym)
+            assert_equal(a10 / y, a10 / ym)
+            assert_equal(x + a10, xm + a10)
+            assert_equal(x - a10, xm - a10)
+            assert_equal(x * a10, xm * a10)
+            assert_equal(x / a10, xm / a10)
+            assert_equal(x**2, xm**2)
+            assert_equal(abs(x)**2.5, abs(xm) **2.5)
+            assert_equal(x**y, xm**ym)
+            assert_equal(np.add(x,y), add(xm, ym))
+            assert_equal(np.subtract(x,y), subtract(xm, ym))
+            assert_equal(np.multiply(x,y), multiply(xm, ym))
+            assert_equal(np.divide(x,y), divide(xm, ym))
+
+    def test_mixed_arithmetic(self):
+        "Tests mixed arithmetics."
+        na = np.array([1])
+        ma = array([1])
+        self.failUnless(isinstance(na + ma, MaskedArray))
+        self.failUnless(isinstance(ma + na, MaskedArray))
+
+
+    def test_limits_arithmetic(self):
+        tiny = np.finfo(float).tiny
+        a = array([tiny, 1./tiny, 0.])
+        assert_equal(getmaskarray(a/2), [0,0,0])
+        assert_equal(getmaskarray(2/a), [1,0,1])
+
+    def test_masked_singleton_arithmetic(self):
+        "Tests some scalar arithmetics on MaskedArrays."
+        # Masked singleton should remain masked no matter what
+        xm = array(0, mask=1)
+        assert((1/array(0)).mask)
+        assert((1 + xm).mask)
+        assert((-xm).mask)
+        assert(maximum(xm, xm).mask)
+        assert(minimum(xm, xm).mask)
+
+    def test_arithmetic_with_masked_singleton(self):
+        "Checks that there's no collapsing to masked"
+        x = masked_array([1,2])
+        y = x * masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y._mask, [True, True])
+        y = x[0] * masked
+        assert y is masked
+        y = x + masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y._mask, [True, True])
+
+
+
+    def test_scalar_arithmetic(self):
+        x = array(0, mask=0)
+        assert_equal(x.filled().ctypes.data, x.ctypes.data)
+        # Make sure we don't lose the shape in some circumstances
+        xm = array((0,0))/0.
+        assert_equal(xm.shape,(2,))
+        assert_equal(xm.mask,[1,1])
+
+    def test_basic_ufuncs (self):
+        "Test various functions such as sin, cos."
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(np.cos(x), cos(xm))
+        assert_equal(np.cosh(x), cosh(xm))
+        assert_equal(np.sin(x), sin(xm))
+        assert_equal(np.sinh(x), sinh(xm))
+        assert_equal(np.tan(x), tan(xm))
+        assert_equal(np.tanh(x), tanh(xm))
+        assert_equal(np.sqrt(abs(x)), sqrt(xm))
+        assert_equal(np.log(abs(x)), log(xm))
+        assert_equal(np.log10(abs(x)), log10(xm))
+        assert_equal(np.exp(x), exp(xm))
+        assert_equal(np.arcsin(z), arcsin(zm))
+        assert_equal(np.arccos(z), arccos(zm))
+        assert_equal(np.arctan(z), arctan(zm))
+        assert_equal(np.arctan2(x, y), arctan2(xm, ym))
+        assert_equal(np.absolute(x), absolute(xm))
+        assert_equal(np.equal(x,y), equal(xm, ym))
+        assert_equal(np.not_equal(x,y), not_equal(xm, ym))
+        assert_equal(np.less(x,y), less(xm, ym))
+        assert_equal(np.greater(x,y), greater(xm, ym))
+        assert_equal(np.less_equal(x,y), less_equal(xm, ym))
+        assert_equal(np.greater_equal(x,y), greater_equal(xm, ym))
+        assert_equal(np.conjugate(x), conjugate(xm))
+
+
+    def test_count_func (self):
+        "Tests count"
+        ott = array([0.,1.,2.,3.], mask=[1,0,0,0])
+        assert( isinstance(count(ott), int))
+        assert_equal(3, count(ott))
+        assert_equal(1, count(1))
+        assert_equal(0, array(1,mask=[1]))
+        ott = ott.reshape((2,2))
+        assert isinstance(count(ott,0), ndarray)
+        assert isinstance(count(ott), types.IntType)
+        assert_equal(3, count(ott))
+        assert getmask(count(ott,0)) is nomask
+        assert_equal([1,2],count(ott,0))
+
+    def test_minmax_func (self):
+        "Tests minimum and maximum."
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        xr = np.ravel(x) #max doesn't work if shaped
+        xmr = ravel(xm)
+        assert_equal(max(xr), maximum(xmr)) #true because of careful selection of data
+        assert_equal(min(xr), minimum(xmr)) #true because of careful selection of data
         #
-        import datetime
-        dt = datetime.datetime.now()
-        a[0] = dt
-        assert(a[0] is dt)
+        assert_equal(minimum([1,2,3],[4,0,9]), [1,0,3])
+        assert_equal(maximum([1,2,3],[4,0,9]), [4,2,9])
+        x = arange(5)
+        y = arange(5) - 2
+        x[3] = masked
+        y[0] = masked
+        assert_equal(minimum(x,y), where(less(x,y), x, y))
+        assert_equal(maximum(x,y), where(greater(x,y), x, y))
+        assert minimum(x) == 0
+        assert maximum(x) == 4
+        #
+        x = arange(4).reshape(2,2)
+        x[-1,-1] = masked
+        assert_equal(maximum(x), 2)
+
+
+    def test_minmax_funcs_with_output(self):
+        "Tests the min/max functions with explicit outputs"
+        mask = np.random.rand(12).round()
+        xm = array(np.random.uniform(0,10,12),mask=mask)
+        xm.shape = (3,4)
+        for funcname in ('min', 'max'):
+            # Initialize
+            npfunc = getattr(np, funcname)
+            mafunc = getattr(coremodule, funcname)
+            # Use the np version
+            nout = np.empty((4,), dtype=int) 
+            result = npfunc(xm,axis=0,out=nout)
+            assert(result is nout)
+            # Use the ma version
+            nout.fill(-999)
+            result = mafunc(xm,axis=0,out=nout)
+            assert(result is nout)
+
+
+    def test_minmax_methods(self):
+        "Additional tests on max/min"
+        (_, _, _, _, _, xm, _, _, _, _) = self.d
+        xm.shape = (xm.size,)
+        assert_equal(xm.max(), 10)
+        assert(xm[0].max() is masked)
+        assert(xm[0].max(0) is masked)
+        assert(xm[0].max(-1) is masked)
+        assert_equal(xm.min(), -10.)
+        assert(xm[0].min() is masked)
+        assert(xm[0].min(0) is masked)
+        assert(xm[0].min(-1) is masked)
+        assert_equal(xm.ptp(), 20.)
+        assert(xm[0].ptp() is masked)
+        assert(xm[0].ptp(0) is masked)
+        assert(xm[0].ptp(-1) is masked)
+        #
+        x = array([1,2,3], mask=True)
+        assert(x.min() is masked)
+        assert(x.max() is masked)
+        assert(x.ptp() is masked)
     #........................
-    def test_maskingfunctions(self):
-        "Tests masking functions."
-        x = array([1.,2.,3.,4.,5.])
-        x[2] = masked
-        assert_equal(masked_where(greater(x, 2), x), masked_greater(x,2))
-        assert_equal(masked_where(greater_equal(x, 2), x), masked_greater_equal(x,2))
-        assert_equal(masked_where(less(x, 2), x), masked_less(x,2))
-        assert_equal(masked_where(less_equal(x, 2), x), masked_less_equal(x,2))
-        assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x,2))
-        assert_equal(masked_where(equal(x, 2), x), masked_equal(x,2))
-        assert_equal(masked_where(not_equal(x,2), x), masked_not_equal(x,2))
-        assert_equal(masked_inside(range(5), 1, 3), [0, 199, 199, 199, 4])
-        assert_equal(masked_outside(range(5), 1, 3),[199,1,2,3,199])
-        assert_equal(masked_inside(array(range(5), mask=[1,0,0,0,0]), 1, 3).mask, [1,1,1,1,0])
-        assert_equal(masked_outside(array(range(5), mask=[0,1,0,0,0]), 1, 3).mask, [1,1,0,0,1])
-        assert_equal(masked_equal(array(range(5), mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,0])
-        assert_equal(masked_not_equal(array([2,2,1,2,1], mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,1])
-        assert_equal(masked_where([1,1,0,0,0], [1,2,3,4,5]), [99,99,3,4,5])
-    #........................
+    def test_addsumprod (self):
+        "Tests add, sum, product."
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(np.add.reduce(x), add.reduce(x))
+        assert_equal(np.add.accumulate(x), add.accumulate(x))
+        assert_equal(4, sum(array(4),axis=0))
+        assert_equal(4, sum(array(4), axis=0))
+        assert_equal(np.sum(x,axis=0), sum(x,axis=0))
+        assert_equal(np.sum(filled(xm,0),axis=0), sum(xm,axis=0))
+        assert_equal(np.sum(x,0), sum(x,0))
+        assert_equal(np.product(x,axis=0), product(x,axis=0))
+        assert_equal(np.product(x,0), product(x,0))
+        assert_equal(np.product(filled(xm,1),axis=0), product(xm,axis=0))
+        s = (3,4)
+        x.shape = y.shape = xm.shape = ym.shape = s
+        if len(s) > 1:
+            assert_equal(np.concatenate((x,y),1), concatenate((xm,ym),1))
+            assert_equal(np.add.reduce(x,1), add.reduce(x,1))
+            assert_equal(np.sum(x,1), sum(x,1))
+            assert_equal(np.product(x,1), product(x,1))
+
+
+
+
     def test_TakeTransposeInnerOuter(self):
         "Test of take, transpose, inner, outer products"
         x = arange(24)
-        y = numpy.arange(24)
+        y = np.arange(24)
         x[5:6] = masked
         x = x.reshape(2,3,4)
         y = y.reshape(2,3,4)
-        assert_equal(numpy.transpose(y,(2,0,1)), transpose(x,(2,0,1)))
-        assert_equal(numpy.take(y, (2,0,1), 1), take(x, (2,0,1), 1))
-        assert_equal(numpy.inner(filled(x,0),filled(y,0)),
+        assert_equal(np.transpose(y,(2,0,1)), transpose(x,(2,0,1)))
+        assert_equal(np.take(y, (2,0,1), 1), take(x, (2,0,1), 1))
+        assert_equal(np.inner(filled(x,0),filled(y,0)),
                             inner(x, y))
-        assert_equal(numpy.outer(filled(x,0),filled(y,0)),
+        assert_equal(np.outer(filled(x,0),filled(y,0)),
                             outer(x, y))
         y = array(['abc', 1, 'def', 2, 3], object)
         y[2] = masked
@@ -682,166 +680,8 @@
         assert t[0] == 'abc'
         assert t[1] == 2
         assert t[2] == 3
-    #.......................
-    def test_maskedelement(self):
-        "Test of masked element"
-        x = arange(6)
-        x[1] = masked
-        assert(str(masked) ==  '--')
-        assert(x[1] is masked)
-        assert_equal(filled(x[1], 0), 0)
-        # don't know why these should raise an exception...
-        #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, masked)
-        #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, 2)
-        #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, xx)
-        #self.failUnlessRaises(Exception, lambda x,y: x+y, xx, masked)
-    #........................
-    def test_scalar(self):
-        "Checks masking a scalar"
-        x = masked_array(0)
-        assert_equal(str(x), '0')
-        x = masked_array(0,mask=True)
-        assert_equal(str(x), str(masked_print_option))
-        x = masked_array(0, mask=False)
-        assert_equal(str(x), '0')
-    #........................
-    def test_usingmasked(self):
-        "Checks that there's no collapsing to masked"
-        x = masked_array([1,2])
-        y = x * masked
-        assert_equal(y.shape, x.shape)
-        assert_equal(y._mask, [True, True])
-        y = x[0] * masked
-        assert y is masked
-        y = x + masked
-        assert_equal(y.shape, x.shape)
-        assert_equal(y._mask, [True, True])
 
-    #........................
-    def test_topython(self):
-        "Tests some communication issues with Python."
-        assert_equal(1, int(array(1)))
-        assert_equal(1.0, float(array(1)))
-        assert_equal(1, int(array([[[1]]])))
-        assert_equal(1.0, float(array([[1]])))
-        self.assertRaises(TypeError, float, array([1,1]))
 
-        warnings.simplefilter('ignore',UserWarning)
-        assert numpy.isnan(float(array([1],mask=[1])))
-        warnings.simplefilter('default',UserWarning)
-        #
-        a = array([1,2,3],mask=[1,0,0])
-        self.assertRaises(TypeError, lambda:float(a))
-        assert_equal(float(a[-1]), 3.)
-        assert(numpy.isnan(float(a[0])))
-        self.assertRaises(TypeError, int, a)
-        assert_equal(int(a[-1]), 3)
-        self.assertRaises(MAError, lambda:int(a[0]))
-    #........................
-    def test_arraymethods(self):
-        "Tests some MaskedArray methods."
-        a = array([1,3,2])
-        b = array([1,3,2], mask=[1,0,1])
-        assert_equal(a.any(), a.data.any())
-        assert_equal(a.all(), a.data.all())
-        assert_equal(a.argmax(), a.data.argmax())
-        assert_equal(a.argmin(), a.data.argmin())
-        assert_equal(a.choose(0,1,2,3,4), a.data.choose(0,1,2,3,4))
-        assert_equal(a.compress([1,0,1]), a.data.compress([1,0,1]))
-        assert_equal(a.conj(), a.data.conj())
-        assert_equal(a.conjugate(), a.data.conjugate())
-        #
-        m = array([[1,2],[3,4]])
-        assert_equal(m.diagonal(), m.data.diagonal())
-        assert_equal(a.sum(), a.data.sum())
-        assert_equal(a.take([1,2]), a.data.take([1,2]))
-        assert_equal(m.transpose(), m.data.transpose())
-    #........................
-    def test_basicattributes(self):
-        "Tests some basic array attributes."
-        a = array([1,3,2])
-        b = array([1,3,2], mask=[1,0,1])
-        assert_equal(a.ndim, 1)
-        assert_equal(b.ndim, 1)
-        assert_equal(a.size, 3)
-        assert_equal(b.size, 3)
-        assert_equal(a.shape, (3,))
-        assert_equal(b.shape, (3,))
-    #........................
-    def test_single_element_subscript(self):
-        "Tests single element subscripts of Maskedarrays."
-        a = array([1,3,2])
-        b = array([1,3,2], mask=[1,0,1])
-        assert_equal(a[0].shape, ())
-        assert_equal(b[0].shape, ())
-        assert_equal(b[1].shape, ())
-    #........................
-    def test_maskcreation(self):
-        "Tests how masks are initialized at the creation of Maskedarrays."
-        data = arange(24, dtype=float_)
-        data[[3,6,15]] = masked
-        dma_1 = MaskedArray(data)
-        assert_equal(dma_1.mask, data.mask)
-        dma_2 = MaskedArray(dma_1)
-        assert_equal(dma_2.mask, dma_1.mask)
-        dma_3 = MaskedArray(dma_1, mask=[1,0,0,0]*6)
-        fail_if_equal(dma_3.mask, dma_1.mask)
-
-    def test_pickling(self):
-        "Tests pickling"
-        import cPickle
-        a = arange(10)
-        a[::3] = masked
-        a.fill_value = 999
-        a_pickled = cPickle.loads(a.dumps())
-        assert_equal(a_pickled._mask, a._mask)
-        assert_equal(a_pickled._data, a._data)
-        assert_equal(a_pickled.fill_value, 999)
-        #
-        a = array(numpy.matrix(range(10)), mask=[1,0,1,0,0]*2)
-        a_pickled = cPickle.loads(a.dumps())
-        assert_equal(a_pickled._mask, a._mask)
-        assert_equal(a_pickled, a)
-        assert(isinstance(a_pickled._data,numpy.matrix))
-    #
-    def test_fillvalue(self):
-        "Having fun with the fill_value"
-        data = masked_array([1,2,3],fill_value=-999)
-        series = data[[0,2,1]]
-        assert_equal(series._fill_value, data._fill_value)
-        #
-        mtype = [('f',float_),('s','|S3')]
-        x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype)
-        x.fill_value=999
-        assert_equal(x.fill_value.item(),[999.,'999'])
-        assert_equal(x['f'].fill_value, 999)
-        assert_equal(x['s'].fill_value, '999')
-        #
-        x.fill_value=(9,'???')
-        assert_equal(x.fill_value.item(), (9,'???'))
-        assert_equal(x['f'].fill_value, 9)
-        assert_equal(x['s'].fill_value, '???')
-        #
-        x = array([1,2,3.1])
-        x.fill_value = 999
-        assert_equal(numpy.asarray(x.fill_value).dtype, float_)
-        assert_equal(x.fill_value, 999.)
-    #
-    def test_asarray(self):
-        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
-        xm.fill_value = -9999
-        xmm = asarray(xm)
-        assert_equal(xmm._data, xm._data)
-        assert_equal(xmm._mask, xm._mask)
-        assert_equal(xmm.fill_value, xm.fill_value)
-    #
-    def test_fix_invalid(self):
-        "Checks fix_invalid."
-        data = masked_array(numpy.sqrt([-1., 0., 1.]), mask=[0,0,1])
-        data_fixed = fix_invalid(data)
-        assert_equal(data_fixed._data, [data.fill_value, 0., 1.])
-        assert_equal(data_fixed._mask, [1., 0., 1.])
-    #
     def test_imag_real(self):
         "Check complex"
         xx = array([1+10j,20+2j], mask=[1,0])
@@ -851,42 +691,136 @@
         assert_equal(xx.real,[1,20])
         assert_equal(xx.real.filled(), [1e+20,20])
         assert_equal(xx.real.dtype, xx._data.real.dtype)
-    #
-    def test_ndmin(self):
-        "Check the use of ndmin"
-        x = array([1,2,3],mask=[1,0,0], ndmin=2)
-        assert_equal(x.shape,(1,3))
-        assert_equal(x._data,[[1,2,3]])
-        assert_equal(x._mask,[[1,0,0]])
-    #
-    def test_record(self):
-        "Check record access"
-        mtype = [('f',float_),('s','|S3')]
-        x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype)
-        x[1] = masked
+
+
+    def test_methods_with_output(self):
+        xm = array(np.random.uniform(0,10,12)).reshape(3,4)
+        xm[:,0] = xm[0] = xm[-1,-1] = masked
         #
-        (xf, xs) = (x['f'], x['s'])
-        assert_equal(xf.data, [1,2,numpy.pi])
-        assert_equal(xf.mask, [0,1,0])
-        assert_equal(xf.dtype, float_)
-        assert_equal(xs.data, ['a', 'b', 'pi'])
-        assert_equal(xs.mask, [0,1,0])
-        assert_equal(xs.dtype, '|S3')
+        funclist = ('sum','prod','var','std', 'max', 'min', 'ptp', 'mean',)
+        #
+        for funcname in funclist:
+            npfunc = getattr(np, funcname)
+            xmmeth = getattr(xm, funcname)
+            
+            # A ndarray as explicit input
+            output = np.empty(4, dtype=float)
+            output.fill(-9999)
+            result = npfunc(xm, axis=0,out=output)
+            # ... the result should be the given output
+            assert(result is output)
+            assert_equal(result, xmmeth(axis=0, out=output))
+            #
+            output = empty(4, dtype=int)
+            result = xmmeth(axis=0, out=output)
+            assert(result is output)
+            assert(output[0] is masked)
+
+#------------------------------------------------------------------------------
+
+class TestMaskedArrayAttributes(NumpyTestCase):
+
+
+    def test_keepmask(self):
+        "Tests the keep mask flag"
+        x = masked_array([1,2,3], mask=[1,0,0])
+        mx = masked_array(x)
+        assert_equal(mx.mask, x.mask)
+        mx = masked_array(x, mask=[0,1,0], keep_mask=False)
+        assert_equal(mx.mask, [0,1,0])
+        mx = masked_array(x, mask=[0,1,0], keep_mask=True)
+        assert_equal(mx.mask, [1,1,0])
+        # We default to true
+        mx = masked_array(x, mask=[0,1,0])
+        assert_equal(mx.mask, [1,1,0])
+
+    def test_hardmask(self):
+        "Test hard_mask"
+        d = arange(5)
+        n = [0,0,0,1,1]
+        m = make_mask(n)
+        xh = array(d, mask = m, hard_mask=True)
+        # We need to copy, to avoid updating d in xh!
+        xs = array(d, mask = m, hard_mask=False, copy=True)
+        xh[[1,4]] = [10,40]
+        xs[[1,4]] = [10,40]
+        assert_equal(xh._data, [0,10,2,3,4])
+        assert_equal(xs._data, [0,10,2,3,40])
+        #assert_equal(xh.mask.ctypes.data, m.ctypes.data)
+        assert_equal(xs.mask, [0,0,0,1,0])
+        assert(xh._hardmask)
+        assert(not xs._hardmask)
+        xh[1:4] = [10,20,30]
+        xs[1:4] = [10,20,30]
+        assert_equal(xh._data, [0,10,20,3,4])
+        assert_equal(xs._data, [0,10,20,30,40])
+        #assert_equal(xh.mask.ctypes.data, m.ctypes.data)
+        assert_equal(xs.mask, nomask)
+        xh[0] = masked
+        xs[0] = masked
+        assert_equal(xh.mask, [1,0,0,1,1])
+        assert_equal(xs.mask, [1,0,0,0,0])
+        xh[:] = 1
+        xs[:] = 1
+        assert_equal(xh._data, [0,1,1,3,4])
+        assert_equal(xs._data, [1,1,1,1,1])
+        assert_equal(xh.mask, [1,0,0,1,1])
+        assert_equal(xs.mask, nomask)
+        # Switch to soft mask
+        xh.soften_mask()
+        xh[:] = arange(5)
+        assert_equal(xh._data, [0,1,2,3,4])
+        assert_equal(xh.mask, nomask)
+        # Switch back to hard mask
+        xh.harden_mask()
+        xh[xh<3] = masked
+        assert_equal(xh._data, [0,1,2,3,4])
+        assert_equal(xh._mask, [1,1,1,0,0])
+        xh[filled(xh>1,False)] = 5
+        assert_equal(xh._data, [0,1,2,5,5])
+        assert_equal(xh._mask, [1,1,1,0,0])
+        #
+        xh = array([[1,2],[3,4]], mask = [[1,0],[0,0]], hard_mask=True)
+        xh[0] = 0
+        assert_equal(xh._data, [[1,0],[3,4]])
+        assert_equal(xh._mask, [[1,0],[0,0]])
+        xh[-1,-1] = 5
+        assert_equal(xh._data, [[1,0],[3,5]])
+        assert_equal(xh._mask, [[1,0],[0,0]])
+        xh[filled(xh<5,False)] = 2
+        assert_equal(xh._data, [[1,2],[2,5]])
+        assert_equal(xh._mask, [[1,0],[0,0]])
+        #
+        "Another test of hardmask"
+        d = arange(5)
+        n = [0,0,0,1,1]
+        m = make_mask(n)
+        xh = array(d, mask = m, hard_mask=True)
+        xh[4:5] = 999
+        #assert_equal(xh.mask.ctypes.data, m.ctypes.data)
+        xh[0:1] = 999
+        assert_equal(xh._data,[999,1,2,3,4])
+
+    def test_smallmask(self):
+        "Checks the behaviour of _smallmask"
+        a = arange(10)
+        a[1] = masked
+        a[1] = 1
+        assert_equal(a._mask, nomask)
+        a = arange(10)
+        a._smallmask = False
+        a[1] = masked
+        a[1] = 1
+        assert_equal(a._mask, zeros(10))
+
+
+#------------------------------------------------------------------------------
+
+class TestFillingValues(NumpyTestCase):
     #
-    def test_set_records(self):
-        "Check setting an element of a record)"
-        mtype = [('f',float_),('s','|S3')]
-        x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype)
-        x[0] = (10,'A')
-        (xf, xs) = (x['f'], x['s'])
-        assert_equal(xf.data, [10,2,numpy.pi])
-        assert_equal(xf.dtype, float_)
-        assert_equal(xs.data, ['A', 'b', 'pi'])
-        assert_equal(xs.dtype, '|S3')
-    #
-    def test_check_fill_value(self):
+    def test_check_on_scalar(self):
         "Test _check_fill_value"
-        _check_fill_value = numpy.ma.core._check_fill_value
+        _check_fill_value = np.ma.core._check_fill_value
         #
         fval = _check_fill_value(0,int)
         assert_equal(fval, 0)
@@ -900,33 +834,34 @@
         #
         fval = _check_fill_value(1e+20,int)
         assert_equal(fval, default_fill_value(0))
-        
-    def test_check_fill_value_with_fields(self):
+
+
+    def test_check_on_fields(self):
         "Tests _check_fill_value with records"
-        _check_fill_value = numpy.ma.core._check_fill_value
-        #
+        _check_fill_value = np.ma.core._check_fill_value
         ndtype = [('a',int),('b',float),('c',"|S3")]
+        # A check on a list should return a single record
         fval = _check_fill_value([-999,-999.9,"???"], ndtype)
         assert(isinstance(fval,ndarray))
         assert_equal(fval.item(), [-999,-999.9,"???"])
-        #
+        # A check on Non should output the defaults
         fval = _check_fill_value(None, ndtype)
         assert(isinstance(fval,ndarray))
         assert_equal(fval.item(), [default_fill_value(0),
                                    default_fill_value(0.),
                                    default_fill_value("0")])
-        #
+        #.....Using a flexi-ndarray as fill_value should work
         fill_val = np.array((-999,-999.9,"???"),dtype=ndtype)
         fval = _check_fill_value(fill_val, ndtype)
         assert(isinstance(fval,ndarray))
         assert_equal(fval.item(), [-999,-999.9,"???"])
-        #
+        #.....Using a flexi-ndarray w/ a different type shouldn't matter
         fill_val = np.array((-999,-999.9,"???"),
                             dtype=[("A",int),("B",float),("C","|S3")])
         fval = _check_fill_value(fill_val, ndtype)
         assert(isinstance(fval,ndarray))
         assert_equal(fval.item(), [-999,-999.9,"???"])
-        #
+        #.....Using an object-array shouldn't matter either
         fill_value =  np.array((-999,-999.9,"???"), dtype=object)
         fval = _check_fill_value(fill_val, ndtype)
         assert(isinstance(fval,ndarray))
@@ -936,12 +871,13 @@
         fval = _check_fill_value(fill_val, ndtype)
         assert(isinstance(fval,ndarray))
         assert_equal(fval.item(), [-999,-999.9,"???"])
-        #
+        #.....One-field-only flexi-ndarray should work as well
         ndtype = [("a",int)]
         fval = _check_fill_value(-999, ndtype)
         assert(isinstance(fval,ndarray))
         assert_equal(fval.item(), (-999,))
-    #
+
+
     def test_fillvalue_conversion(self):
         "Tests the behavior of fill_value during conversion"
         # We had a tailored comment to make sure special attributes are properly
@@ -967,8 +903,31 @@
         assert_equal(b['a'].fill_value, a.fill_value)
 
 
-#...............................................................................
+    def test_fillvalue(self):
+        "Yet more fun with the fill_value"
+        data = masked_array([1,2,3],fill_value=-999)
+        series = data[[0,2,1]]
+        assert_equal(series._fill_value, data._fill_value)
+        #
+        mtype = [('f',float_),('s','|S3')]
+        x = array([(1,'a'),(2,'b'),(np.pi,'pi')], dtype=mtype)
+        x.fill_value=999
+        assert_equal(x.fill_value.item(),[999.,'999'])
+        assert_equal(x['f'].fill_value, 999)
+        assert_equal(x['s'].fill_value, '999')
+        #
+        x.fill_value=(9,'???')
+        assert_equal(x.fill_value.item(), (9,'???'))
+        assert_equal(x['f'].fill_value, 9)
+        assert_equal(x['s'].fill_value, '???')
+        #
+        x = array([1,2,3.1])
+        x.fill_value = 999
+        assert_equal(np.asarray(x.fill_value).dtype, float_)
+        assert_equal(x.fill_value, 999.)
 
+#------------------------------------------------------------------------------
+
 class TestUfuncs(NumpyTestCase):
     "Test class for the application of ufuncs on MaskedArrays."
     def setUp(self):
@@ -997,7 +956,6 @@
                   'less', 'greater',
                   'logical_and', 'logical_or', 'logical_xor',
                   ]:
-            #print f
             try:
                 uf = getattr(umath, f)
             except AttributeError:
@@ -1028,31 +986,147 @@
         assert_equal(amask.min(0), [5,6,7,8])
         assert(amask.max(1)[0].mask)
         assert(amask.min(1)[0].mask)
-    #........................
-    def test_minmax_funcs_with_out(self):
-        mask = numpy.random.rand(12).round()
-        xm = array(numpy.random.uniform(0,10,12),mask=mask)
-        xm.shape = (3,4)
-        for funcname in ('min', 'max'):
-            # Initialize
-            npfunc = getattr(numpy, funcname)
-            mafunc = getattr(coremodule, funcname)
-            # Use the np version
-            nout = np.empty((4,), dtype=int) 
-            result = npfunc(xm,axis=0,out=nout)
-            assert(result is nout)
-            # Use the ma version
-            nout.fill(-999)
-            result = mafunc(xm,axis=0,out=nout)
-            assert(result is nout)
 
-#...............................................................................
 
-class TestArrayMathMethods(NumpyTestCase):
+#------------------------------------------------------------------------------
+
+class TestMaskedArrayInPlaceArithmetics(NumpyTestCase):
+    "Test MaskedArray Arithmetics"
+    
+    def setUp(self):
+        x = arange(10)
+        y = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        self.intdata = (x, y, xm)
+        self.floatdata = (x.astype(float), y.astype(float), xm.astype(float))
+
+    def test_inplace_addition_scalar(self):
+        """Test of inplace additions"""
+        (x, y, xm) = self.intdata
+        xm[2] = masked
+        x += 1
+        assert_equal(x, y+1)
+        xm += 1
+        assert_equal(xm, y+1)
+        #
+        warnings.simplefilter('ignore', DeprecationWarning)
+        (x, _, xm) = self.floatdata
+        id1 = x.raw_data().ctypes.data
+        x += 1.
+        assert (id1 == x.raw_data().ctypes.data)
+        assert_equal(x, y+1.)
+        warnings.simplefilter('default', DeprecationWarning)
+
+    def test_inplace_addition_array(self):
+        """Test of inplace additions"""
+        (x, y, xm) = self.intdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x += a
+        xm += a
+        assert_equal(x,y+a)
+        assert_equal(xm,y+a)
+        assert_equal(xm.mask, mask_or(m,a.mask))
+
+    def test_inplace_subtraction_scalar(self):
+        """Test of inplace subtractions"""
+        (x, y, xm) = self.intdata
+        x -= 1
+        assert_equal(x, y-1)
+        xm -= 1
+        assert_equal(xm, y-1)
+
+    def test_inplace_subtraction_array(self):
+        """Test of inplace subtractions"""
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float_)
+        a[-1] = masked
+        x -= a
+        xm -= a
+        assert_equal(x,y-a)
+        assert_equal(xm,y-a)
+        assert_equal(xm.mask, mask_or(m,a.mask))
+
+    def test_inplace_multiplication_scalar(self):
+        """Test of inplace multiplication"""
+        (x, y, xm) = self.floatdata
+        x *= 2.0
+        assert_equal(x, y*2)
+        xm *= 2.0
+        assert_equal(xm, y*2)
+
+    def test_inplace_multiplication_array(self):
+        """Test of inplace multiplication"""
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float_)
+        a[-1] = masked
+        x *= a
+        xm *= a
+        assert_equal(x,y*a)
+        assert_equal(xm,y*a)
+        assert_equal(xm.mask, mask_or(m,a.mask))
+
+    def test_inplace_division_scalar_int(self):
+        """Test of inplace division"""
+        (x, y, xm) = self.intdata
+        x = arange(10)*2
+        xm = arange(10)*2
+        xm[2] = masked
+        x /= 2
+        assert_equal(x, y)
+        xm /= 2
+        assert_equal(xm, y)
+
+    def test_inplace_division_scalar_float(self):
+        """Test of inplace division"""
+        (x, y, xm) = self.floatdata
+        x /= 2.0
+        assert_equal(x, y/2.0)
+        xm /= arange(10)
+        assert_equal(xm, ones((10,)))
+
+    def test_inplace_division_array_float(self):
+        """Test of inplace division"""
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float_)
+        a[-1] = masked
+        x /= a
+        xm /= a
+        assert_equal(x,y/a)
+        assert_equal(xm,y/a)
+        assert_equal(xm.mask, mask_or(mask_or(m,a.mask), (a==0)))
+
+    def test_inplace_division_misc(self):
+        #
+        x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        #
+        z = xm/ym
+        assert_equal(z._mask, [1,1,1,0,0,1,1,0,0,0,1,1])
+        assert_equal(z._data, [0.2,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.])
+        #
+        xm = xm.copy()
+        xm /= ym
+        assert_equal(xm._mask, [1,1,1,0,0,1,1,0,0,0,1,1])
+        assert_equal(xm._data, [1/5.,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.])
+
+
+#------------------------------------------------------------------------------
+
+class TestMaskedArrayMethods(NumpyTestCase):
     "Test class for miscellaneous MaskedArrays methods."
     def setUp(self):
         "Base data definition."
-        x = numpy.array([ 8.375,  7.545,  8.828,  8.5  ,  1.757,  5.928,
+        x = np.array([ 8.375,  7.545,  8.828,  8.5  ,  1.757,  5.928,
                       8.43 ,  7.78 ,  9.865,  5.878,  8.979,  4.732,
                       3.012,  6.022,  5.095,  3.116,  5.238,  3.957,
                       6.04 ,  9.63 ,  7.712,  3.382,  4.489,  6.479,
@@ -1061,7 +1135,7 @@
         X = x.reshape(6,6)
         XX = x.reshape(3,2,2,3)
 
-        m = numpy.array([0, 1, 0, 1, 0, 0,
+        m = np.array([0, 1, 0, 1, 0, 0,
                      1, 0, 1, 1, 0, 1,
                      0, 0, 0, 1, 0, 1,
                      0, 0, 0, 1, 1, 1,
@@ -1071,7 +1145,7 @@
         mX = array(data=X,mask=m.reshape(X.shape))
         mXX = array(data=XX,mask=m.reshape(XX.shape))
 
-        m2 = numpy.array([1, 1, 0, 1, 0, 0,
+        m2 = np.array([1, 1, 0, 1, 0, 0,
                       1, 1, 1, 1, 0, 1,
                       0, 0, 1, 1, 0, 1,
                       0, 0, 0, 1, 1, 1,
@@ -1082,78 +1156,103 @@
         m2XX = array(data=XX,mask=m2.reshape(XX.shape))
         self.d =  (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX)
 
-    #------------------------------------------------------
-    def test_trace(self):
-        "Tests trace on MaskedArrays."
-        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
-        mXdiag = mX.diagonal()
-        assert_equal(mX.trace(), mX.diagonal().compressed().sum())
-        assert_almost_equal(mX.trace(),
-                            X.trace() - sum(mXdiag.mask*X.diagonal(),axis=0))
+    def test_generic_methods(self):
+        "Tests some MaskedArray methods."
+        a = array([1,3,2])
+        b = array([1,3,2], mask=[1,0,1])
+        assert_equal(a.any(), a.data.any())
+        assert_equal(a.all(), a.data.all())
+        assert_equal(a.argmax(), a.data.argmax())
+        assert_equal(a.argmin(), a.data.argmin())
+        assert_equal(a.choose(0,1,2,3,4), a.data.choose(0,1,2,3,4))
+        assert_equal(a.compress([1,0,1]), a.data.compress([1,0,1]))
+        assert_equal(a.conj(), a.data.conj())
+        assert_equal(a.conjugate(), a.data.conjugate())
+        #
+        m = array([[1,2],[3,4]])
+        assert_equal(m.diagonal(), m.data.diagonal())
+        assert_equal(a.sum(), a.data.sum())
+        assert_equal(a.take([1,2]), a.data.take([1,2]))
+        assert_equal(m.transpose(), m.data.transpose())
 
-    def test_clip(self):
-        "Tests clip on MaskedArrays."
-        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
-        clipped = mx.clip(2,8)
-        assert_equal(clipped.mask,mx.mask)
-        assert_equal(clipped.data,x.clip(2,8))
-        assert_equal(clipped.data,mx.data.clip(2,8))
 
-    def test_ptp(self):
-        "Tests ptp on MaskedArrays."
-        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
-        (n,m) = X.shape
-        assert_equal(mx.ptp(),mx.compressed().ptp())
-        rows = numpy.zeros(n,numpy.float_)
-        cols = numpy.zeros(m,numpy.float_)
-        for k in range(m):
-            cols[k] = mX[:,k].compressed().ptp()
-        for k in range(n):
-            rows[k] = mX[k].compressed().ptp()
-        assert_equal(mX.ptp(0),cols)
-        assert_equal(mX.ptp(1),rows)
+    def test_allany(self):
+        """Checks the any/all methods/functions."""
+        x = np.array([[ 0.13,  0.26,  0.90],
+                     [ 0.28,  0.33,  0.63],
+                     [ 0.31,  0.87,  0.70]])
+        m = np.array([[ True, False, False],
+                     [False, False, False],
+                     [True,  True, False]], dtype=np.bool_)
+        mx = masked_array(x, mask=m)
+        xbig = np.array([[False, False,  True],
+                        [False, False,  True],
+                        [False,  True,  True]], dtype=np.bool_)
+        mxbig = (mx > 0.5)
+        mxsmall = (mx < 0.5)
+        #
+        assert (mxbig.all()==False)
+        assert (mxbig.any()==True)
+        assert_equal(mxbig.all(0),[False, False, True])
+        assert_equal(mxbig.all(1), [False, False, True])
+        assert_equal(mxbig.any(0),[False, False, True])
+        assert_equal(mxbig.any(1), [True, True, True])
+        #
+        assert (mxsmall.all()==False)
+        assert (mxsmall.any()==True)
+        assert_equal(mxsmall.all(0), [True,   True, False])
+        assert_equal(mxsmall.all(1), [False, False, False])
+        assert_equal(mxsmall.any(0), [True,   True, False])
+        assert_equal(mxsmall.any(1), [True,   True, False])
 
-    def test_swapaxes(self):
-        "Tests swapaxes on MaskedArrays."
-        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
-        mXswapped = mX.swapaxes(0,1)
-        assert_equal(mXswapped[-1],mX[:,-1])
-        mXXswapped = mXX.swapaxes(0,2)
-        assert_equal(mXXswapped.shape,(2,2,3,3))
 
-    def test_cumsumprod(self):
-        "Tests cumsum & cumprod on MaskedArrays."
-        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
-        mXcp = mX.cumsum(0)
-        assert_equal(mXcp.data,mX.filled(0).cumsum(0))
-        mXcp = mX.cumsum(1)
-        assert_equal(mXcp.data,mX.filled(0).cumsum(1))
+    def test_allany_onmatrices(self):
+        x = np.array([[ 0.13,  0.26,  0.90],
+                     [ 0.28,  0.33,  0.63],
+                     [ 0.31,  0.87,  0.70]])
+        X = np.matrix(x)
+        m = np.array([[ True, False, False],
+                     [False, False, False],
+                     [True,  True, False]], dtype=np.bool_)
+        mX = masked_array(X, mask=m)
+        mXbig = (mX > 0.5)
+        mXsmall = (mX < 0.5)
         #
-        mXcp = mX.cumprod(0)
-        assert_equal(mXcp.data,mX.filled(1).cumprod(0))
-        mXcp = mX.cumprod(1)
-        assert_equal(mXcp.data,mX.filled(1).cumprod(1))
+        assert (mXbig.all()==False)
+        assert (mXbig.any()==True)
+        assert_equal(mXbig.all(0), np.matrix([False, False, True]))
+        assert_equal(mXbig.all(1), np.matrix([False, False, True]).T)
+        assert_equal(mXbig.any(0), np.matrix([False, False, True]))
+        assert_equal(mXbig.any(1), np.matrix([ True,  True, True]).T)
+        #
+        assert (mXsmall.all()==False)
+        assert (mXsmall.any()==True)
+        assert_equal(mXsmall.all(0), np.matrix([True,   True, False]))
+        assert_equal(mXsmall.all(1), np.matrix([False, False, False]).T)
+        assert_equal(mXsmall.any(0), np.matrix([True,   True, False]))
+        assert_equal(mXsmall.any(1), np.matrix([True,   True, False]).T)
 
-    def test_varstd(self):
-        "Tests var & std on MaskedArrays."
-        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
-        assert_almost_equal(mX.var(axis=None),mX.compressed().var())
-        assert_almost_equal(mX.std(axis=None),mX.compressed().std())
-        assert_almost_equal(mX.std(axis=None,ddof=1),
-                            mX.compressed().std(ddof=1))
-        assert_almost_equal(mX.var(axis=None,ddof=1),
-                            mX.compressed().var(ddof=1))
-        assert_equal(mXX.var(axis=3).shape,XX.var(axis=3).shape)
-        assert_equal(mX.var().shape,X.var().shape)
-        (mXvar0,mXvar1) = (mX.var(axis=0), mX.var(axis=1))
-        assert_almost_equal(mX.var(axis=None,ddof=2),mX.compressed().var(ddof=2))
-        assert_almost_equal(mX.std(axis=None,ddof=2),mX.compressed().std(ddof=2))
-        for k in range(6):
-            assert_almost_equal(mXvar1[k],mX[k].compressed().var())
-            assert_almost_equal(mXvar0[k],mX[:,k].compressed().var())
-            assert_almost_equal(numpy.sqrt(mXvar0[k]), mX[:,k].compressed().std())
 
-    def test_argmin(self):
+    def test_allany_oddities(self):
+        "Some fun with all and any"
+        store = empty(1, dtype=bool)
+        full = array([1,2,3], mask=True)
+        #
+        assert(full.all() is masked)
+        full.all(out=store)
+        assert(store)
+        assert(store._mask, True)
+        assert(store is not masked)
+        #
+        store = empty(1, dtype=bool)
+        assert(full.any() is masked)
+        full.any(out=store)
+        assert(not store)
+        assert(store._mask, True)
+        assert(store is not masked)
+
+
+    def test_argmax_argmin(self):
         "Tests argmin & argmax on MaskedArrays."
         (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
         #
@@ -1176,6 +1275,90 @@
         assert_equal(mX.argmax(1), [2,4,1,1,4,1])
         assert_equal(m2X.argmax(1), [2,4,1,1,1,1])
 
+
+    def test_clip(self):
+        "Tests clip on MaskedArrays."
+        x = np.array([ 8.375,  7.545,  8.828,  8.5  ,  1.757,  5.928,
+                       8.43 ,  7.78 ,  9.865,  5.878,  8.979,  4.732,
+                       3.012,  6.022,  5.095,  3.116,  5.238,  3.957,
+                       6.04 ,  9.63 ,  7.712,  3.382,  4.489,  6.479,
+                       7.189,  9.645,  5.395,  4.961,  9.894,  2.893,
+                       7.357,  9.828,  6.272,  3.758,  6.693,  0.993])
+        m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0])
+        mx = array(x,mask=m)
+        clipped = mx.clip(2,8)
+        assert_equal(clipped.mask,mx.mask)
+        assert_equal(clipped.data,x.clip(2,8))
+        assert_equal(clipped.data,mx.data.clip(2,8))
+
+
+    def test_compress(self):
+        "test compress"
+        a = masked_array([1., 2., 3., 4., 5.], fill_value=9999)
+        condition = (a > 1.5) & (a < 3.5)
+        assert_equal(a.compress(condition),[2.,3.])
+        #
+        a[[2,3]] = masked
+        b = a.compress(condition)
+        assert_equal(b._data,[2.,3.])
+        assert_equal(b._mask,[0,1])
+        assert_equal(b.fill_value,9999)
+        assert_equal(b,a[condition])
+        #
+        condition = (a<4.)
+        b = a.compress(condition)
+        assert_equal(b._data,[1.,2.,3.])
+        assert_equal(b._mask,[0,0,1])
+        assert_equal(b.fill_value,9999)
+        assert_equal(b,a[condition])
+        #
+        a = masked_array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0]])
+        b = a.compress(a.ravel() >= 22)
+        assert_equal(b._data, [30, 40, 50, 60])
+        assert_equal(b._mask, [1,1,0,0])
+        #
+        x = np.array([3,1,2])
+        b = a.compress(x >= 2, axis=1)
+        assert_equal(b._data, [[10,30],[40,60]])
+        assert_equal(b._mask, [[0,1],[1,0]])
+
+
+    def test_compressed(self):
+        "Tests compressed"
+        a = array([1,2,3,4],mask=[0,0,0,0])
+        b = a.compressed()
+        assert_equal(b, a)
+        a[0] = masked
+        b = a.compressed()
+        assert_equal(b, [2,3,4])
+        #
+        a = array(np.matrix([1,2,3,4]), mask=[0,0,0,0])
+        b = a.compressed()
+        assert_equal(b,a)
+        assert(isinstance(b,np.matrix))
+        a[0,0] = masked
+        b = a.compressed()
+        assert_equal(b, [[2,3,4]])
+
+
+    def test_empty(self):
+        "Tests empty/like"
+        datatype = [('a',int_),('b',float_),('c','|S8')]
+        a = masked_array([(1,1.1,'1.1'),(2,2.2,'2.2'),(3,3.3,'3.3')],
+                         dtype=datatype)
+        assert_equal(len(a.fill_value.item()), len(datatype))
+        #
+        b = empty_like(a)
+        assert_equal(b.shape, a.shape)
+        assert_equal(b.fill_value, a.fill_value)
+        #
+        b = empty(len(a), dtype=datatype)
+        assert_equal(b.shape, a.shape)
+        assert_equal(b.fill_value, a.fill_value)
+
+
     def test_put(self):
         "Tests put."
         d = arange(5)
@@ -1207,6 +1390,7 @@
         assert_array_equal(x, [0,1,2,3,4,5,6,7,8,9,])
         assert_equal(x.mask, [1,0,0,0,1,1,0,0,0,0])
 
+
     def test_put_hardmask(self):
         "Tests put on hardmask"
         d = arange(5)
@@ -1216,184 +1400,76 @@
         xh.put([4,2,0,1,3],[1,2,3,4,5])
         assert_equal(xh._data, [3,4,2,4,5])
 
-    def test_take(self):
-        "Tests take"
-        x = masked_array([10,20,30,40],[0,1,0,1])
-        assert_equal(x.take([0,0,3]), masked_array([10, 10, 40], [0,0,1]) )
-        assert_equal(x.take([0,0,3]), x[[0,0,3]])
-        assert_equal(x.take([[0,1],[0,1]]),
-                     masked_array([[10,20],[10,20]], [[0,1],[0,1]]) )
-        #
-        x = array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0,]])
-        assert_equal(x.take([0,2], axis=1),
-                     array([[10,30],[40,60]], mask=[[0,1],[1,0]]))
-        assert_equal(take(x, [0,2], axis=1),
-                      array([[10,30],[40,60]], mask=[[0,1],[1,0]]))
-        #........................
-    def test_anyall(self):
-        """Checks the any/all methods/functions."""
-        x = numpy.array([[ 0.13,  0.26,  0.90],
-                     [ 0.28,  0.33,  0.63],
-                     [ 0.31,  0.87,  0.70]])
-        m = numpy.array([[ True, False, False],
-                     [False, False, False],
-                     [True,  True, False]], dtype=numpy.bool_)
-        mx = masked_array(x, mask=m)
-        xbig = numpy.array([[False, False,  True],
-                        [False, False,  True],
-                        [False,  True,  True]], dtype=numpy.bool_)
-        mxbig = (mx > 0.5)
-        mxsmall = (mx < 0.5)
-        #
-        assert (mxbig.all()==False)
-        assert (mxbig.any()==True)
-        assert_equal(mxbig.all(0),[False, False, True])
-        assert_equal(mxbig.all(1), [False, False, True])
-        assert_equal(mxbig.any(0),[False, False, True])
-        assert_equal(mxbig.any(1), [True, True, True])
-        #
-        assert (mxsmall.all()==False)
-        assert (mxsmall.any()==True)
-        assert_equal(mxsmall.all(0), [True,   True, False])
-        assert_equal(mxsmall.all(1), [False, False, False])
-        assert_equal(mxsmall.any(0), [True,   True, False])
-        assert_equal(mxsmall.any(1), [True,   True, False])
-        #
-        X = numpy.matrix(x)
-        mX = masked_array(X, mask=m)
-        mXbig = (mX > 0.5)
-        mXsmall = (mX < 0.5)
-        #
-        assert (mXbig.all()==False)
-        assert (mXbig.any()==True)
-        assert_equal(mXbig.all(0), numpy.matrix([False, False, True]))
-        assert_equal(mXbig.all(1), numpy.matrix([False, False, True]).T)
-        assert_equal(mXbig.any(0), numpy.matrix([False, False, True]))
-        assert_equal(mXbig.any(1), numpy.matrix([ True,  True, True]).T)
-        #
-        assert (mXsmall.all()==False)
-        assert (mXsmall.any()==True)
-        assert_equal(mXsmall.all(0), numpy.matrix([True,   True, False]))
-        assert_equal(mXsmall.all(1), numpy.matrix([False, False, False]).T)
-        assert_equal(mXsmall.any(0), numpy.matrix([True,   True, False]))
-        assert_equal(mXsmall.any(1), numpy.matrix([True,   True, False]).T)
 
+    def test_putmask(self):
+        x = arange(6)+1
+        mx = array(x, mask=[0,0,0,1,1,1])
+        mask = [0,0,1,0,0,1]
+        # w/o mask, w/o masked values
+        xx = x.copy()
+        putmask(xx, mask, 99)
+        assert_equal(xx, [1,2,99,4,5,99])
+        # w/ mask, w/o masked values
+        mxx = mx.copy()
+        putmask(mxx, mask, 99)
+        assert_equal(mxx._data, [1,2,99,4,5,99])
+        assert_equal(mxx._mask, [0,0,0,1,1,0])
+        # w/o mask, w/ masked values
+        values = array([10,20,30,40,50,60],mask=[1,1,1,0,0,0])
+        xx = x.copy()
+        putmask(xx, mask, values)
+        assert_equal(xx._data, [1,2,30,4,5,60])
+        assert_equal(xx._mask, [0,0,1,0,0,0])
+        # w/ mask, w/ masked values
+        mxx = mx.copy()
+        putmask(mxx, mask, values)
+        assert_equal(mxx._data, [1,2,30,4,5,60])
+        assert_equal(mxx._mask, [0,0,1,1,1,0])
+        # w/ mask, w/ masked values + hardmask
+        mxx = mx.copy()
+        mxx.harden_mask()
+        putmask(mxx, mask, values)
+        assert_equal(mxx, [1,2,30,4,5,60])
 
-    def test_allany_oddities(self):
-        "Some fun with all and any"
-        store = empty(1, dtype=bool)
-        full = array([1,2,3], mask=True)
-        #
-        assert(full.all() is masked)
-        full.all(out=store)
-        assert(store)
-        assert(store._mask, True)
-        assert(store is not masked)
-        #
-        store = empty(1, dtype=bool)
-        assert(full.any() is masked)
-        full.any(out=store)
-        assert(not store)
-        assert(store._mask, True)
-        assert(store is not masked)
 
+    def test_ravel(self):
+        "Tests ravel"
+        a = array([[1,2,3,4,5]], mask=[[0,1,0,0,0]])
+        aravel = a.ravel()
+        assert_equal(a._mask.shape, a.shape)
+        a = array([0,0], mask=[1,1])
+        aravel = a.ravel()
+        assert_equal(a._mask.shape, a.shape)
+        a = array(np.matrix([1,2,3,4,5]), mask=[[0,1,0,0,0]])
+        aravel = a.ravel()
+        assert_equal(a.shape,(1,5))
+        assert_equal(a._mask.shape, a.shape)
+        # Checs that small_mask is preserved
+        a = array([1,2,3,4],mask=[0,0,0,0],shrink=False)
+        assert_equal(a.ravel()._mask, [0,0,0,0])
+        # Test that the fill_value is preserved
+        a.fill_value = -99
+        a.shape = (2,2)
+        ar = a.ravel()
+        assert_equal(ar._mask, [0,0,0,0])
+        assert_equal(ar._data, [1,2,3,4])
+        assert_equal(ar.fill_value, -99)
 
-    def test_keepmask(self):
-        "Tests the keep mask flag"
-        x = masked_array([1,2,3], mask=[1,0,0])
-        mx = masked_array(x)
-        assert_equal(mx.mask, x.mask)
-        mx = masked_array(x, mask=[0,1,0], keep_mask=False)
-        assert_equal(mx.mask, [0,1,0])
-        mx = masked_array(x, mask=[0,1,0], keep_mask=True)
-        assert_equal(mx.mask, [1,1,0])
-        # We default to true
-        mx = masked_array(x, mask=[0,1,0])
-        assert_equal(mx.mask, [1,1,0])
 
-    def test_hardmask(self):
-        "Test hard_mask"
-        d = arange(5)
-        n = [0,0,0,1,1]
-        m = make_mask(n)
-        xh = array(d, mask = m, hard_mask=True)
-        # We need to copy, to avoid updating d in xh!
-        xs = array(d, mask = m, hard_mask=False, copy=True)
-        xh[[1,4]] = [10,40]
-        xs[[1,4]] = [10,40]
-        assert_equal(xh._data, [0,10,2,3,4])
-        assert_equal(xs._data, [0,10,2,3,40])
-        #assert_equal(xh.mask.ctypes.data, m.ctypes.data)
-        assert_equal(xs.mask, [0,0,0,1,0])
-        assert(xh._hardmask)
-        assert(not xs._hardmask)
-        xh[1:4] = [10,20,30]
-        xs[1:4] = [10,20,30]
-        assert_equal(xh._data, [0,10,20,3,4])
-        assert_equal(xs._data, [0,10,20,30,40])
-        #assert_equal(xh.mask.ctypes.data, m.ctypes.data)
-        assert_equal(xs.mask, nomask)
-        xh[0] = masked
-        xs[0] = masked
-        assert_equal(xh.mask, [1,0,0,1,1])
-        assert_equal(xs.mask, [1,0,0,0,0])
-        xh[:] = 1
-        xs[:] = 1
-        assert_equal(xh._data, [0,1,1,3,4])
-        assert_equal(xs._data, [1,1,1,1,1])
-        assert_equal(xh.mask, [1,0,0,1,1])
-        assert_equal(xs.mask, nomask)
-        # Switch to soft mask
-        xh.soften_mask()
-        xh[:] = arange(5)
-        assert_equal(xh._data, [0,1,2,3,4])
-        assert_equal(xh.mask, nomask)
-        # Switch back to hard mask
-        xh.harden_mask()
-        xh[xh<3] = masked
-        assert_equal(xh._data, [0,1,2,3,4])
-        assert_equal(xh._mask, [1,1,1,0,0])
-        xh[filled(xh>1,False)] = 5
-        assert_equal(xh._data, [0,1,2,5,5])
-        assert_equal(xh._mask, [1,1,1,0,0])
-        #
-        xh = array([[1,2],[3,4]], mask = [[1,0],[0,0]], hard_mask=True)
-        xh[0] = 0
-        assert_equal(xh._data, [[1,0],[3,4]])
-        assert_equal(xh._mask, [[1,0],[0,0]])
-        xh[-1,-1] = 5
-        assert_equal(xh._data, [[1,0],[3,5]])
-        assert_equal(xh._mask, [[1,0],[0,0]])
-        xh[filled(xh<5,False)] = 2
-        assert_equal(xh._data, [[1,2],[2,5]])
-        assert_equal(xh._mask, [[1,0],[0,0]])
-        #
-        "Another test of hardmask"
-        d = arange(5)
-        n = [0,0,0,1,1]
-        m = make_mask(n)
-        xh = array(d, mask = m, hard_mask=True)
-        xh[4:5] = 999
-        #assert_equal(xh.mask.ctypes.data, m.ctypes.data)
-        xh[0:1] = 999
-        assert_equal(xh._data,[999,1,2,3,4])
+    def test_reshape(self):
+        "Tests reshape"
+        x = arange(4)
+        x[0] = masked
+        y = x.reshape(2,2)
+        assert_equal(y.shape, (2,2,))
+        assert_equal(y._mask.shape, (2,2,))
+        assert_equal(x.shape, (4,))
+        assert_equal(x._mask.shape, (4,))
 
-    def test_smallmask(self):
-        "Checks the behaviour of _smallmask"
-        a = arange(10)
-        a[1] = masked
-        a[1] = 1
-        assert_equal(a._mask, nomask)
-        a = arange(10)
-        a._smallmask = False
-        a[1] = masked
-        a[1] = 1
-        assert_equal(a._mask, zeros(10))
 
-
     def test_sort(self):
         "Test sort"
-        x = array([1,4,2,3],mask=[0,1,0,0],dtype=numpy.uint8)
+        x = array([1,4,2,3],mask=[0,1,0,0],dtype=np.uint8)
         #
         sortedx = sort(x)
         assert_equal(sortedx._data,[1,2,3,4])
@@ -1407,7 +1483,7 @@
         assert_equal(x._data,[1,2,3,4])
         assert_equal(x._mask,[0,0,0,1])
         #
-        x = array([1,4,2,3],mask=[0,1,0,0],dtype=numpy.uint8)
+        x = array([1,4,2,3],mask=[0,1,0,0],dtype=np.uint8)
         x.sort(endwith=False)
         assert_equal(x._data, [4,1,2,3])
         assert_equal(x._mask, [1,0,0,0])
@@ -1416,14 +1492,15 @@
         sortedx = sort(x)
         assert(not isinstance(sorted, MaskedArray))
         #
-        x = array([0,1,-1,-2,2], mask=nomask, dtype=numpy.int8)
+        x = array([0,1,-1,-2,2], mask=nomask, dtype=np.int8)
         sortedx = sort(x, endwith=False)
         assert_equal(sortedx._data, [-2,-1,0,1,2])
-        x = array([0,1,-1,-2,2], mask=[0,1,0,0,1], dtype=numpy.int8)
+        x = array([0,1,-1,-2,2], mask=[0,1,0,0,1], dtype=np.int8)
         sortedx = sort(x, endwith=False)
         assert_equal(sortedx._data, [1,2,-2,-1,0])
         assert_equal(sortedx._mask, [1,1,0,0,0])
 
+
     def test_sort_2d(self):
         "Check sort of 2D array."
         # 2D array w/o mask
@@ -1465,60 +1542,59 @@
         assert_equal(am, an)
 
 
-    def test_ravel(self):
-        "Tests ravel"
-        a = array([[1,2,3,4,5]], mask=[[0,1,0,0,0]])
-        aravel = a.ravel()
-        assert_equal(a._mask.shape, a.shape)
-        a = array([0,0], mask=[1,1])
-        aravel = a.ravel()
-        assert_equal(a._mask.shape, a.shape)
-        a = array(numpy.matrix([1,2,3,4,5]), mask=[[0,1,0,0,0]])
-        aravel = a.ravel()
-        assert_equal(a.shape,(1,5))
-        assert_equal(a._mask.shape, a.shape)
-        # Checs that small_mask is preserved
-        a = array([1,2,3,4],mask=[0,0,0,0],shrink=False)
-        assert_equal(a.ravel()._mask, [0,0,0,0])
-        # Test that the fill_value is preserved
-        a.fill_value = -99
-        a.shape = (2,2)
-        ar = a.ravel()
-        assert_equal(ar._mask, [0,0,0,0])
-        assert_equal(ar._data, [1,2,3,4])
-        assert_equal(ar.fill_value, -99)
+    def test_squeeze(self):
+        "Check squeeze"
+        data = masked_array([[1,2,3]])
+        assert_equal(data.squeeze(), [1,2,3])
+        data = masked_array([[1,2,3]], mask=[[1,1,1]])
+        assert_equal(data.squeeze(), [1,2,3])
+        assert_equal(data.squeeze()._mask, [1,1,1])
+        data = masked_array([[1]], mask=True)
+        assert(data.squeeze() is masked)
 
-    def test_reshape(self):
-        "Tests reshape"
-        x = arange(4)
-        x[0] = masked
-        y = x.reshape(2,2)
-        assert_equal(y.shape, (2,2,))
-        assert_equal(y._mask.shape, (2,2,))
-        assert_equal(x.shape, (4,))
-        assert_equal(x._mask.shape, (4,))
 
-    def test_compressed(self):
-        "Tests compressed"
-        a = array([1,2,3,4],mask=[0,0,0,0])
-        b = a.compressed()
-        assert_equal(b, a)
-        a[0] = masked
-        b = a.compressed()
-        assert_equal(b, [2,3,4])
+    def test_swapaxes(self):
+        "Tests swapaxes on MaskedArrays."
+        x = np.array([ 8.375,  7.545,  8.828,  8.5  ,  1.757,  5.928,
+                      8.43 ,  7.78 ,  9.865,  5.878,  8.979,  4.732,
+                      3.012,  6.022,  5.095,  3.116,  5.238,  3.957,
+                      6.04 ,  9.63 ,  7.712,  3.382,  4.489,  6.479,
+                      7.189,  9.645,  5.395,  4.961,  9.894,  2.893,
+                      7.357,  9.828,  6.272,  3.758,  6.693,  0.993])
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mX = array(x,mask=m).reshape(6,6)
+        mXX = mX.reshape(3,2,2,3)
         #
-        a = array(numpy.matrix([1,2,3,4]), mask=[0,0,0,0])
-        b = a.compressed()
-        assert_equal(b,a)
-        assert(isinstance(b,numpy.matrix))
-        a[0,0] = masked
-        b = a.compressed()
-        assert_equal(b, [[2,3,4]])
+        mXswapped = mX.swapaxes(0,1)
+        assert_equal(mXswapped[-1],mX[:,-1])
+        
+        mXXswapped = mXX.swapaxes(0,2)
+        assert_equal(mXXswapped.shape,(2,2,3,3))
 
 
+    def test_take(self):
+        "Tests take"
+        x = masked_array([10,20,30,40],[0,1,0,1])
+        assert_equal(x.take([0,0,3]), masked_array([10, 10, 40], [0,0,1]) )
+        assert_equal(x.take([0,0,3]), x[[0,0,3]])
+        assert_equal(x.take([[0,1],[0,1]]),
+                     masked_array([[10,20],[10,20]], [[0,1],[0,1]]) )
+        #
+        x = array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0,]])
+        assert_equal(x.take([0,2], axis=1),
+                     array([[10,30],[40,60]], mask=[[0,1],[1,0]]))
+        assert_equal(take(x, [0,2], axis=1),
+                      array([[10,30],[40,60]], mask=[[0,1],[1,0]]))
+
+
     def test_tolist(self):
         "Tests to list"
-        x = array(numpy.arange(12))
+        x = array(np.arange(12))
         x[[1,-2]] = masked
         xlist = x.tolist()
         assert(xlist[1] is None)
@@ -1539,92 +1615,124 @@
         assert_equal(x.tolist(), [(1,1.1,'one'),(2,2.2,'two'),(None,None,None)])
 
 
-    def test_squeeze(self):
-        "Check squeeze"
-        data = masked_array([[1,2,3]])
-        assert_equal(data.squeeze(), [1,2,3])
-        data = masked_array([[1,2,3]], mask=[[1,1,1]])
-        assert_equal(data.squeeze(), [1,2,3])
-        assert_equal(data.squeeze()._mask, [1,1,1])
-        data = masked_array([[1]], mask=True)
-        assert(data.squeeze() is masked)
+#------------------------------------------------------------------------------
 
-    def test_putmask(self):
-        x = arange(6)+1
-        mx = array(x, mask=[0,0,0,1,1,1])
-        mask = [0,0,1,0,0,1]
-        # w/o mask, w/o masked values
-        xx = x.copy()
-        putmask(xx, mask, 99)
-        assert_equal(xx, [1,2,99,4,5,99])
-        # w/ mask, w/o masked values
-        mxx = mx.copy()
-        putmask(mxx, mask, 99)
-        assert_equal(mxx._data, [1,2,99,4,5,99])
-        assert_equal(mxx._mask, [0,0,0,1,1,0])
-        # w/o mask, w/ masked values
-        values = array([10,20,30,40,50,60],mask=[1,1,1,0,0,0])
-        xx = x.copy()
-        putmask(xx, mask, values)
-        assert_equal(xx._data, [1,2,30,4,5,60])
-        assert_equal(xx._mask, [0,0,1,0,0,0])
-        # w/ mask, w/ masked values
-        mxx = mx.copy()
-        putmask(mxx, mask, values)
-        assert_equal(mxx._data, [1,2,30,4,5,60])
-        assert_equal(mxx._mask, [0,0,1,1,1,0])
-        # w/ mask, w/ masked values + hardmask
-        mxx = mx.copy()
-        mxx.harden_mask()
-        putmask(mxx, mask, values)
-        assert_equal(mxx, [1,2,30,4,5,60])
 
-    def test_compress(self):
-        "test compress"
-        a = masked_array([1., 2., 3., 4., 5.], fill_value=9999)
-        condition = (a > 1.5) & (a < 3.5)
-        assert_equal(a.compress(condition),[2.,3.])
+class TestMaskArrayMathMethod(NumpyTestCase):
+
+    def setUp(self):
+        "Base data definition."
+        x = np.array([ 8.375,  7.545,  8.828,  8.5  ,  1.757,  5.928,
+                      8.43 ,  7.78 ,  9.865,  5.878,  8.979,  4.732,
+                      3.012,  6.022,  5.095,  3.116,  5.238,  3.957,
+                      6.04 ,  9.63 ,  7.712,  3.382,  4.489,  6.479,
+                      7.189,  9.645,  5.395,  4.961,  9.894,  2.893,
+                      7.357,  9.828,  6.272,  3.758,  6.693,  0.993])
+        X = x.reshape(6,6)
+        XX = x.reshape(3,2,2,3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x,mask=m)
+        mX = array(data=X,mask=m.reshape(X.shape))
+        mXX = array(data=XX,mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x,mask=m2)
+        m2X = array(data=X,mask=m2.reshape(X.shape))
+        m2XX = array(data=XX,mask=m2.reshape(XX.shape))
+        self.d =  (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX)
+
+
+    def test_cumsumprod(self):
+        "Tests cumsum & cumprod on MaskedArrays."
+        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
+        mXcp = mX.cumsum(0)
+        assert_equal(mXcp.data,mX.filled(0).cumsum(0))
+        mXcp = mX.cumsum(1)
+        assert_equal(mXcp.data,mX.filled(0).cumsum(1))
         #
-        a[[2,3]] = masked
-        b = a.compress(condition)
-        assert_equal(b._data,[2.,3.])
-        assert_equal(b._mask,[0,1])
-        assert_equal(b.fill_value,9999)
-        assert_equal(b,a[condition])
+        mXcp = mX.cumprod(0)
+        assert_equal(mXcp.data,mX.filled(1).cumprod(0))
+        mXcp = mX.cumprod(1)
+        assert_equal(mXcp.data,mX.filled(1).cumprod(1))
+
+
+    def test_cumsumprod_with_output(self):
+        "Tests cumsum/cumprod w/ output"
+        xm = array(np.random.uniform(0,10,12)).reshape(3,4)
+        xm[:,0] = xm[0] = xm[-1,-1] = masked
         #
-        condition = (a<4.)
-        b = a.compress(condition)
-        assert_equal(b._data,[1.,2.,3.])
-        assert_equal(b._mask,[0,0,1])
-        assert_equal(b.fill_value,9999)
-        assert_equal(b,a[condition])
-        #
-        a = masked_array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0]])
-        b = a.compress(a.ravel() >= 22)
-        assert_equal(b._data, [30, 40, 50, 60])
-        assert_equal(b._mask, [1,1,0,0])
-        #
-        x = numpy.array([3,1,2])
-        b = a.compress(x >= 2, axis=1)
-        assert_equal(b._data, [[10,30],[40,60]])
-        assert_equal(b._mask, [[0,1],[1,0]])
-    #
-    def test_empty(self):
-        "Tests empty/like"
-        datatype = [('a',int_),('b',float_),('c','|S8')]
-        a = masked_array([(1,1.1,'1.1'),(2,2.2,'2.2'),(3,3.3,'3.3')],
-                         dtype=datatype)
-        assert_equal(len(a.fill_value.item()), len(datatype))
-        #
-        b = empty_like(a)
-        assert_equal(b.shape, a.shape)
-        assert_equal(b.fill_value, a.fill_value)
-        #
-        b = empty(len(a), dtype=datatype)
-        assert_equal(b.shape, a.shape)
-        assert_equal(b.fill_value, a.fill_value)
+        for funcname in ('cumsum','cumprod'):
+            npfunc = getattr(np, funcname)
+            xmmeth = getattr(xm, funcname)
+            
+            # A ndarray as explicit input
+            output = np.empty((3,4), dtype=float)
+            output.fill(-9999)
+            result = npfunc(xm, axis=0,out=output)
+            # ... the result should be the given output
+            assert(result is output)
+            assert_equal(result, xmmeth(axis=0, out=output))
+            #
+            output = empty((3,4), dtype=int)
+            result = xmmeth(axis=0, out=output)
+            assert(result is output)
 
 
+    def test_ptp(self):
+        "Tests ptp on MaskedArrays."
+        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
+        (n,m) = X.shape
+        assert_equal(mx.ptp(),mx.compressed().ptp())
+        rows = np.zeros(n,np.float_)
+        cols = np.zeros(m,np.float_)
+        for k in range(m):
+            cols[k] = mX[:,k].compressed().ptp()
+        for k in range(n):
+            rows[k] = mX[k].compressed().ptp()
+        assert_equal(mX.ptp(0),cols)
+        assert_equal(mX.ptp(1),rows)
+
+
+    def test_trace(self):
+        "Tests trace on MaskedArrays."
+        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
+        mXdiag = mX.diagonal()
+        assert_equal(mX.trace(), mX.diagonal().compressed().sum())
+        assert_almost_equal(mX.trace(),
+                            X.trace() - sum(mXdiag.mask*X.diagonal(),axis=0))
+
+
+    def test_varstd(self):
+        "Tests var & std on MaskedArrays."
+        (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
+        assert_almost_equal(mX.var(axis=None),mX.compressed().var())
+        assert_almost_equal(mX.std(axis=None),mX.compressed().std())
+        assert_almost_equal(mX.std(axis=None,ddof=1),
+                            mX.compressed().std(ddof=1))
+        assert_almost_equal(mX.var(axis=None,ddof=1),
+                            mX.compressed().var(ddof=1))
+        assert_equal(mXX.var(axis=3).shape,XX.var(axis=3).shape)
+        assert_equal(mX.var().shape,X.var().shape)
+        (mXvar0,mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        assert_almost_equal(mX.var(axis=None,ddof=2),mX.compressed().var(ddof=2))
+        assert_almost_equal(mX.std(axis=None,ddof=2),mX.compressed().std(ddof=2))
+        for k in range(6):
+            assert_almost_equal(mXvar1[k],mX[k].compressed().var())
+            assert_almost_equal(mXvar0[k],mX[:,k].compressed().var())
+            assert_almost_equal(np.sqrt(mXvar0[k]), mX[:,k].compressed().std())
+
+
     def test_varstd_specialcases(self):
         "Test a special case for var"
         nout = np.empty(1, dtype=float)
@@ -1659,13 +1767,13 @@
             _ = method(out=nout, ddof=1)
             assert(np.isnan(nout))
 
+#------------------------------------------------------------------------------
 
-
-class TestArrayMathMethodsComplex(NumpyTestCase):
+class TestMaskedArrayMathMethodsComplex(NumpyTestCase):
     "Test class for miscellaneous MaskedArrays methods."
     def setUp(self):
         "Base data definition."
-        x = numpy.array([ 8.375j,  7.545j,  8.828j,  8.5j  ,  1.757j,  5.928,
+        x = np.array([ 8.375j,  7.545j,  8.828j,  8.5j  ,  1.757j,  5.928,
                       8.43 ,  7.78 ,  9.865,  5.878,  8.979,  4.732,
                       3.012,  6.022,  5.095,  3.116,  5.238,  3.957,
                       6.04 ,  9.63 ,  7.712,  3.382,  4.489,  6.479j,
@@ -1674,7 +1782,7 @@
         X = x.reshape(6,6)
         XX = x.reshape(3,2,2,3)
 
-        m = numpy.array([0, 1, 0, 1, 0, 0,
+        m = np.array([0, 1, 0, 1, 0, 0,
                      1, 0, 1, 1, 0, 1,
                      0, 0, 0, 1, 0, 1,
                      0, 0, 0, 1, 1, 1,
@@ -1684,7 +1792,7 @@
         mX = array(data=X,mask=m.reshape(X.shape))
         mXX = array(data=XX,mask=m.reshape(XX.shape))
 
-        m2 = numpy.array([1, 1, 0, 1, 0, 0,
+        m2 = np.array([1, 1, 0, 1, 0, 0,
                       1, 1, 1, 1, 0, 1,
                       0, 0, 1, 1, 0, 1,
                       0, 0, 0, 1, 1, 1,
@@ -1709,19 +1817,65 @@
         for k in range(6):
             assert_almost_equal(mXvar1[k],mX[k].compressed().var())
             assert_almost_equal(mXvar0[k],mX[:,k].compressed().var())
-            assert_almost_equal(numpy.sqrt(mXvar0[k]), mX[:,k].compressed().std())
+            assert_almost_equal(np.sqrt(mXvar0[k]), mX[:,k].compressed().std())
 
-#..............................................................................
 
-class TestMiscFunctions(NumpyTestCase):
+#------------------------------------------------------------------------------
+
+class TestMaskedArrayFunctions(NumpyTestCase):
     "Test class for miscellaneous functions."
     #
-    def test_masked_where(self):
+    def setUp(self):
+        x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0,1,0,0])
+        xf = np.where(m1, 1.e+20, x)
+        xm.set_fill_value(1.e+20)
+        self.info = (xm, ym)
+        
+    #
+    def test_masked_where_bool(self):
         x = [1,2]
         y = masked_where(False,x)
         assert_equal(y,[1,2])
         assert_equal(y[1],2)
-    #
+
+    def test_masked_where_condition(self):
+        "Tests masking functions."
+        x = array([1.,2.,3.,4.,5.])
+        x[2] = masked
+        assert_equal(masked_where(greater(x, 2), x), masked_greater(x,2))
+        assert_equal(masked_where(greater_equal(x, 2), x), masked_greater_equal(x,2))
+        assert_equal(masked_where(less(x, 2), x), masked_less(x,2))
+        assert_equal(masked_where(less_equal(x, 2), x), masked_less_equal(x,2))
+        assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x,2))
+        assert_equal(masked_where(equal(x, 2), x), masked_equal(x,2))
+        assert_equal(masked_where(not_equal(x,2), x), masked_not_equal(x,2))
+        assert_equal(masked_where([1,1,0,0,0], [1,2,3,4,5]), [99,99,3,4,5])
+
+    def test_masked_where_oddities(self):
+        """Tests some generic features."""
+        atest = ones((10,10,10), dtype=float_)
+        btest = zeros(atest.shape, MaskType)
+        ctest = masked_where(btest,atest)
+        assert_equal(atest,ctest)
+
+
+    def test_masked_otherfunctions(self):
+        assert_equal(masked_inside(range(5), 1, 3), [0, 199, 199, 199, 4])
+        assert_equal(masked_outside(range(5), 1, 3),[199,1,2,3,199])
+        assert_equal(masked_inside(array(range(5), mask=[1,0,0,0,0]), 1, 3).mask, [1,1,1,1,0])
+        assert_equal(masked_outside(array(range(5), mask=[0,1,0,0,0]), 1, 3).mask, [1,1,0,0,1])
+        assert_equal(masked_equal(array(range(5), mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,0])
+        assert_equal(masked_not_equal(array([2,2,1,2,1], mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,1])
+
+
     def test_round(self):
         a = array([1.23456, 2.34567, 3.45678, 4.56789, 5.67890],
                   mask=[0,1,0,0,0])
@@ -1731,12 +1885,45 @@
         b = empty_like(a)
         a.round(out=b)
         assert_equal(b, [1., 2., 3., 5., 6.])
-    #
+    
+        x = array([1.,2.,3.,4.,5.])
+        c = array([1,1,1,0,0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1.,2.,0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1.,2.,0., -4., -5])
+        assert z[0] is masked
+        assert z[1] is not masked
+        assert z[2] is masked
+
+
+    def test_round_with_output(self):
+        "Testing round with an explicit output"
+        
+        xm = array(np.random.uniform(0,10,12)).reshape(3,4)
+        xm[:,0] = xm[0] = xm[-1,-1] = masked
+        
+        # A ndarray as explicit input
+        output = np.empty((3,4), dtype=float)
+        output.fill(-9999)
+        result = np.round(xm, decimals=2,out=output)
+        # ... the result should be the given output
+        assert(result is output)
+        assert_equal(result, xm.round(decimals=2, out=output))
+        #
+        output = empty((3,4), dtype=float)
+        result = xm.round(decimals=2, out=output)
+        assert(result is output)
+
+
     def test_identity(self):
         a = identity(5)
         assert(isinstance(a, MaskedArray))
-        assert_equal(a, numpy.identity(5))
-    #
+        assert_equal(a, np.identity(5))
+
+
     def test_power(self):
         x = -1.1
         assert_almost_equal(power(x,2.), 1.21)
@@ -1759,6 +1946,89 @@
         assert_almost_equal(x._data,y._data)
 
 
+    def test_where(self):
+        "Test the where function"
+        x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0,1,0,0])
+        xf = np.where(m1, 1.e+20, x)
+        xm.set_fill_value(1.e+20)
+        
+        d = where(xm>2,xm,-9)
+        assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.])
+        assert_equal(d._mask, xm._mask)
+        d = where(xm>2,-9,ym)
+        assert_equal(d, [5.,0.,3., 2., -1.,-9.,-9., -10., -9., 1., 0., -9.])
+        assert_equal(d._mask, [1,0,1,0,0,0,1,0,0,0,0,0])
+        d = where(xm>2, xm, masked)
+        assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.])
+        tmp = xm._mask.copy()
+        tmp[(xm<=2).filled(True)] = True
+        assert_equal(d._mask, tmp)
+        #
+        ixm = xm.astype(int_)
+        d = where(ixm>2, ixm, masked)
+        assert_equal(d, [-9,-9,-9,-9, -9, 4, -9, -9, 10, -9, -9, 3])
+        assert_equal(d.dtype, ixm.dtype)
+
+    def test_where_with_masked_choice(self):
+        x = arange(10)
+        x[3] = masked
+        c = x >= 8
+        # Set False to masked
+        z = where(c , x, masked)
+        assert z.dtype is x.dtype
+        assert z[3] is masked
+        assert z[4] is masked
+        assert z[7] is masked
+        assert z[8] is not masked
+        assert z[9] is not masked
+        assert_equal(x,z)
+        # Set True to masked
+        z = where(c , masked, x)
+        assert z.dtype is x.dtype
+        assert z[3] is masked
+        assert z[4] is not masked
+        assert z[7] is not masked
+        assert z[8] is masked
+        assert z[9] is masked
+
+    def test_where_with_masked_condition(self):
+        x = array([1.,2.,3.,4.,5.])
+        c = array([1,1,1,0,0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1.,2.,0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1.,2.,0., -4., -5])
+        assert z[0] is masked
+        assert z[1] is not masked
+        assert z[2] is masked
+        #        
+        x = arange(1,6)
+        x[-1] = masked
+        y = arange(1,6)*10
+        y[2] = masked
+        c = array([1,1,1,0,0], mask=[1,0,0,0,0])
+        cm = c.filled(1)
+        z = where(c,x,y)
+        zm = where(cm,x,y)
+        assert_equal(z, zm)
+        assert getmask(zm) is nomask
+        assert_equal(zm, [1,2,3,40,50])
+        z = where(c, masked, 1)
+        assert_equal(z, [99,99,99,1,1])
+        z = where(c, 1, masked)
+        assert_equal(z, [99, 1, 1, 99, 99])
+
+
     def test_choose(self):
         "Test choose"
         choices = [[0, 1, 2, 3], [10, 11, 12, 13],
@@ -1805,71 +2075,78 @@
         chosen = choose(indices_, choices, mode='wrap', out=store)
         assert_equal(store, array([999999, 31, 12, 999999]))
 
-    def test_functions_with_output(self):
-        xm = array(np.random.uniform(0,10,12)).reshape(3,4)
-        xm[:,0] = xm[0] = xm[-1,-1] = masked
-        #
-        funclist = ('sum','prod','var','std', 'max', 'min', 'ptp', 'mean', )
-        #
-        for funcname in funclist:
-            npfunc = getattr(np, funcname)
-            xmmeth = getattr(xm, funcname)
-            
-            # A ndarray as explicit input
-            output = np.empty(4, dtype=float)
-            output.fill(-9999)
-            result = npfunc(xm, axis=0,out=output)
-            # ... the result should be the given output
-            assert(result is output)
-            assert_equal(result, xmmeth(axis=0, out=output))
-            #
-            output = empty(4, dtype=int)
-            result = xmmeth(axis=0, out=output)
-            assert(result is output)
-            assert(output[0] is masked)
 
+#------------------------------------------------------------------------------
 
-    def test_cumsumprod_with_output(self):
-        "Tests cumsum/cumprod w/ output"
-        xm = array(np.random.uniform(0,10,12)).reshape(3,4)
-        xm[:,0] = xm[0] = xm[-1,-1] = masked
-        #
-        funclist = ('cumsum','cumprod')
-        #
-        for funcname in funclist:
-            npfunc = getattr(np, funcname)
-            xmmeth = getattr(xm, funcname)
-            
-            # A ndarray as explicit input
-            output = np.empty((3,4), dtype=float)
-            output.fill(-9999)
-            result = npfunc(xm, axis=0,out=output)
-            # ... the result should be the given output
-            assert(result is output)
-            assert_equal(result, xmmeth(axis=0, out=output))
-            #
-            output = empty((3,4), dtype=int)
-            result = xmmeth(axis=0, out=output)
-            assert(result is output)
+class TestMaskedFields(NumpyTestCase):
+    #
+    def setUp(self):
+        ilist = [1,2,3,4,5]
+        flist = [1.1,2.2,3.3,4.4,5.5]
+        slist = ['one','two','three','four','five']
+        ddtype = [('a',int),('b',float),('c','|S8')]
+        mdtype = [('a',bool),('b',bool),('c',bool)]
+        mask = [0,1,0,0,1]
+        base = array(zip(ilist,flist,slist), mask=mask, dtype=ddtype)
+        self.data = dict(base=base, mask=mask, ddtype=ddtype, mdtype=mdtype)
 
+    def test_set_records_masks(self):
+        base = self.data['base']
+        mdtype = self.data['mdtype']
+        # Set w/ nomask or masked
+        base.mask = nomask
+        assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
+        base.mask = masked
+        assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
+        # Set w/ simple boolean
+        base.mask = False
+        assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
+        base.mask = True
+        assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
+        # Set w/ list
+        base.mask = [0,0,0,1,1]
+        assert_equal_records(base._mask, 
+                             np.array([(x,x,x) for x in [0,0,0,1,1]], 
+                                      dtype=mdtype))
 
-    def test_round_with_output(self):
-        "Testing round with an explicit output"
+    def test_set_record_element(self):
+        "Check setting an element of a record)"
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[0] = (np.pi, np.pi, 'pi')
         
-        xm = array(np.random.uniform(0,10,12)).reshape(3,4)
-        xm[:,0] = xm[0] = xm[-1,-1] = masked
+        assert_equal(base_a.dtype, int)
+        assert_equal(base_a.data, [3,2,3,4,5])
         
-        # A ndarray as explicit input
-        output = np.empty((3,4), dtype=float)
-        output.fill(-9999)
-        result = np.round(xm, decimals=2,out=output)
-        # ... the result should be the given output
-        assert(result is output)
-        assert_equal(result, xm.round(decimals=2, out=output))
+        assert_equal(base_b.dtype, float)
+        assert_equal(base_b.data, [np.pi, 2.2, 3.3, 4.4, 5.5])
+        
+        assert_equal(base_c.dtype, '|S8')
+        assert_equal(base_c.data, ['pi','two','three','four','five'])
+
+    def test_set_record_slice(self):
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[:3] = (np.pi, np.pi, 'pi')
+        
+        assert_equal(base_a.dtype, int)
+        assert_equal(base_a.data, [3,3,3,4,5])
+        
+        assert_equal(base_b.dtype, float)
+        assert_equal(base_b.data, [np.pi, np.pi, np.pi, 4.4, 5.5])
+        
+        assert_equal(base_c.dtype, '|S8')
+        assert_equal(base_c.data, ['pi','pi','pi','four','five'])
+
+    def test_mask_element(self):
+        "Check record access"
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[0] = masked
         #
-        output = empty((3,4), dtype=float)
-        result = xm.round(decimals=2, out=output)
-        assert(result is output)
+        for n in ('a','b','c'):
+            assert_equal(base[n].mask, [1,1,0,0,1])
+            assert_equal(base[n].data, base.data[n])
 
 ###############################################################################
 #------------------------------------------------------------------------------

Modified: trunk/numpy/ma/tests/test_extras.py
===================================================================
--- trunk/numpy/ma/tests/test_extras.py	2008-06-08 18:10:55 UTC (rev 5263)
+++ trunk/numpy/ma/tests/test_extras.py	2008-06-08 23:04:42 UTC (rev 5264)
@@ -11,7 +11,7 @@
 __revision__ = "$Revision: 3473 $"
 __date__     = '$Date: 2007-10-29 17:18:13 +0200 (Mon, 29 Oct 2007) $'
 
-import numpy as N
+import numpy as np
 from numpy.testing import NumpyTest, NumpyTestCase
 from numpy.testing.utils import build_err_msg
 
@@ -52,12 +52,15 @@
         assert_equal(average(x, axis=0), 2.5)
         assert_equal(average(x, axis=0, weights=w1), 2.5)
         y = array([arange(6, dtype=float_), 2.0*arange(6)])
-        assert_equal(average(y, None), N.add.reduce(N.arange(6))*3./12.)
-        assert_equal(average(y, axis=0), N.arange(6) * 3./2.)
-        assert_equal(average(y, axis=1), [average(x,axis=0), average(x,axis=0) * 2.0])
+        assert_equal(average(y, None), np.add.reduce(np.arange(6))*3./12.)
+        assert_equal(average(y, axis=0), np.arange(6) * 3./2.)
+        assert_equal(average(y, axis=1), 
+                     [average(x,axis=0), average(x,axis=0) * 2.0])
         assert_equal(average(y, None, weights=w2), 20./6.)
-        assert_equal(average(y, axis=0, weights=w2), [0.,1.,2.,3.,4.,10.])
-        assert_equal(average(y, axis=1), [average(x,axis=0), average(x,axis=0) * 2.0])
+        assert_equal(average(y, axis=0, weights=w2), 
+                     [0.,1.,2.,3.,4.,10.])
+        assert_equal(average(y, axis=1), 
+                     [average(x,axis=0), average(x,axis=0) * 2.0])
         m1 = zeros(6)
         m2 = [0,0,1,1,0,0]
         m3 = [[0,0,1,1,0,0],[0,1,1,1,1,0]]
@@ -115,26 +118,26 @@
         "Tests mr_ on 2D arrays."
         a_1 = rand(5,5)
         a_2 = rand(5,5)
-        m_1 = N.round_(rand(5,5),0)
-        m_2 = N.round_(rand(5,5),0)
+        m_1 = np.round_(rand(5,5),0)
+        m_2 = np.round_(rand(5,5),0)
         b_1 = masked_array(a_1,mask=m_1)
         b_2 = masked_array(a_2,mask=m_2)
         d = mr_['1',b_1,b_2]  # append columns
         assert(d.shape == (5,10))
         assert_array_equal(d[:,:5],b_1)
         assert_array_equal(d[:,5:],b_2)
-        assert_array_equal(d.mask, N.r_['1',m_1,m_2])
+        assert_array_equal(d.mask, np.r_['1',m_1,m_2])
         d = mr_[b_1,b_2]
         assert(d.shape == (10,5))
         assert_array_equal(d[:5,:],b_1)
         assert_array_equal(d[5:,:],b_2)
-        assert_array_equal(d.mask, N.r_[m_1,m_2])
+        assert_array_equal(d.mask, np.r_[m_1,m_2])
 
 class TestNotMasked(NumpyTestCase):
     "Tests notmasked_edges and notmasked_contiguous."
     def check_edges(self):
         "Tests unmasked_edges"
-        a = masked_array(N.arange(24).reshape(3,8),
+        a = masked_array(np.arange(24).reshape(3,8),
                          mask=[[0,0,0,0,1,1,1,0],
                                [1,1,1,1,1,1,1,1],
                                [0,0,0,0,0,0,1,0],])
@@ -151,7 +154,7 @@
 
     def check_contiguous(self):
         "Tests notmasked_contiguous"
-        a = masked_array(N.arange(24).reshape(3,8),
+        a = masked_array(np.arange(24).reshape(3,8),
                          mask=[[0,0,0,0,1,1,1,1],
                                [1,1,1,1,1,1,1,1],
                                [0,0,0,0,0,0,1,0],])
@@ -176,7 +179,7 @@
     "Tests 2D functions"
     def check_compress2d(self):
         "Tests compress2d"
-        x = array(N.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]])
+        x = array(np.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]])
         assert_equal(compress_rowcols(x), [[4,5],[7,8]] )
         assert_equal(compress_rowcols(x,0), [[3,4,5],[6,7,8]] )
         assert_equal(compress_rowcols(x,1), [[1,2],[4,5],[7,8]] )
@@ -195,7 +198,7 @@
     #
     def check_mask_rowcols(self):
         "Tests mask_rowcols."
-        x = array(N.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]])
+        x = array(np.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]])
         assert_equal(mask_rowcols(x).mask, [[1,1,1],[1,0,0],[1,0,0]] )
         assert_equal(mask_rowcols(x,0).mask, [[1,1,1],[0,0,0],[0,0,0]] )
         assert_equal(mask_rowcols(x,1).mask, [[1,0,0],[1,0,0],[1,0,0]] )
@@ -208,13 +211,16 @@
         assert_equal(mask_rowcols(x,0).mask, [[1,1,1],[1,1,1],[0,0,0]] )
         assert_equal(mask_rowcols(x,1,).mask, [[1,1,0],[1,1,0],[1,1,0]] )
         x = array(x._data, mask=[[1,0,0],[0,1,0],[0,0,1]])
-        assert(mask_rowcols(x).all())
-        assert(mask_rowcols(x,0).all())
-        assert(mask_rowcols(x,1).all())
+        assert(mask_rowcols(x).all() is masked)
+        assert(mask_rowcols(x,0).all() is masked)
+        assert(mask_rowcols(x,1).all() is masked)
+        assert(mask_rowcols(x).mask.all())
+        assert(mask_rowcols(x,0).mask.all())
+        assert(mask_rowcols(x,1).mask.all())
     #
     def test_dot(self):
         "Tests dot product"
-        n = N.arange(1,7)
+        n = np.arange(1,7)
         #
         m = [1,0,0,0,0,0]
         a = masked_array(n, mask=m).reshape(2,3)
@@ -224,9 +230,9 @@
         c = dot(b,a,True)
         assert_equal(c.mask, [[1,1,1],[1,0,0],[1,0,0]])
         c = dot(a,b,False)
-        assert_equal(c, N.dot(a.filled(0), b.filled(0)))
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
         c = dot(b,a,False)
-        assert_equal(c, N.dot(b.filled(0), a.filled(0)))
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
         #
         m = [0,0,0,0,0,1]
         a = masked_array(n, mask=m).reshape(2,3)
@@ -236,10 +242,10 @@
         c = dot(b,a,True)
         assert_equal(c.mask, [[0,0,1],[0,0,1],[1,1,1]])
         c = dot(a,b,False)
-        assert_equal(c, N.dot(a.filled(0), b.filled(0)))
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
         assert_equal(c, dot(a,b))
         c = dot(b,a,False)
-        assert_equal(c, N.dot(b.filled(0), a.filled(0)))
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
         #
         m = [0,0,0,0,0,0]
         a = masked_array(n, mask=m).reshape(2,3)
@@ -254,37 +260,37 @@
         c = dot(a,b,True)
         assert_equal(c.mask,[[1,1],[0,0]])
         c = dot(a,b,False)
-        assert_equal(c, N.dot(a.filled(0),b.filled(0)))
+        assert_equal(c, np.dot(a.filled(0),b.filled(0)))
         c = dot(b,a,True)
         assert_equal(c.mask,[[1,0,0],[1,0,0],[1,0,0]])
         c = dot(b,a,False)
-        assert_equal(c, N.dot(b.filled(0),a.filled(0)))
+        assert_equal(c, np.dot(b.filled(0),a.filled(0)))
         #
         a = masked_array(n, mask=[0,0,0,0,0,1]).reshape(2,3)
         b = masked_array(n, mask=[0,0,0,0,0,0]).reshape(3,2)
         c = dot(a,b,True)
         assert_equal(c.mask,[[0,0],[1,1]])
         c = dot(a,b)
-        assert_equal(c, N.dot(a.filled(0),b.filled(0)))
+        assert_equal(c, np.dot(a.filled(0),b.filled(0)))
         c = dot(b,a,True)
         assert_equal(c.mask,[[0,0,1],[0,0,1],[0,0,1]])
         c = dot(b,a,False)
-        assert_equal(c, N.dot(b.filled(0), a.filled(0)))
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
         #
         a = masked_array(n, mask=[0,0,0,0,0,1]).reshape(2,3)
         b = masked_array(n, mask=[0,0,1,0,0,0]).reshape(3,2)
         c = dot(a,b,True)
         assert_equal(c.mask,[[1,0],[1,1]])
         c = dot(a,b,False)
-        assert_equal(c, N.dot(a.filled(0),b.filled(0)))
+        assert_equal(c, np.dot(a.filled(0),b.filled(0)))
         c = dot(b,a,True)
         assert_equal(c.mask,[[0,0,1],[1,1,1],[0,0,1]])
         c = dot(b,a,False)
-        assert_equal(c, N.dot(b.filled(0),a.filled(0)))
+        assert_equal(c, np.dot(b.filled(0),a.filled(0)))
 
     def test_ediff1d(self):
         "Tests mediff1d"
-        x = masked_array(N.arange(5), mask=[1,0,0,0,1])
+        x = masked_array(np.arange(5), mask=[1,0,0,0,1])
         difx_d = (x._data[1:]-x._data[:-1])
         difx_m = (x._mask[1:]-x._mask[:-1])
         dx = ediff1d(x)
@@ -292,29 +298,29 @@
         assert_equal(dx._mask, difx_m)
         #
         dx = ediff1d(x, to_begin=masked)
-        assert_equal(dx._data, N.r_[0,difx_d])
-        assert_equal(dx._mask, N.r_[1,difx_m])
+        assert_equal(dx._data, np.r_[0,difx_d])
+        assert_equal(dx._mask, np.r_[1,difx_m])
         dx = ediff1d(x, to_begin=[1,2,3])
-        assert_equal(dx._data, N.r_[[1,2,3],difx_d])
-        assert_equal(dx._mask, N.r_[[0,0,0],difx_m])
+        assert_equal(dx._data, np.r_[[1,2,3],difx_d])
+        assert_equal(dx._mask, np.r_[[0,0,0],difx_m])
         #
         dx = ediff1d(x, to_end=masked)
-        assert_equal(dx._data, N.r_[difx_d,0])
-        assert_equal(dx._mask, N.r_[difx_m,1])
+        assert_equal(dx._data, np.r_[difx_d,0])
+        assert_equal(dx._mask, np.r_[difx_m,1])
         dx = ediff1d(x, to_end=[1,2,3])
-        assert_equal(dx._data, N.r_[difx_d,[1,2,3]])
-        assert_equal(dx._mask, N.r_[difx_m,[0,0,0]])
+        assert_equal(dx._data, np.r_[difx_d,[1,2,3]])
+        assert_equal(dx._mask, np.r_[difx_m,[0,0,0]])
         #
         dx = ediff1d(x, to_end=masked, to_begin=masked)
-        assert_equal(dx._data, N.r_[0,difx_d,0])
-        assert_equal(dx._mask, N.r_[1,difx_m,1])
+        assert_equal(dx._data, np.r_[0,difx_d,0])
+        assert_equal(dx._mask, np.r_[1,difx_m,1])
         dx = ediff1d(x, to_end=[1,2,3], to_begin=masked)
-        assert_equal(dx._data, N.r_[0,difx_d,[1,2,3]])
-        assert_equal(dx._mask, N.r_[1,difx_m,[0,0,0]])
+        assert_equal(dx._data, np.r_[0,difx_d,[1,2,3]])
+        assert_equal(dx._mask, np.r_[1,difx_m,[0,0,0]])
         #
         dx = ediff1d(x._data, to_end=masked, to_begin=masked)
-        assert_equal(dx._data, N.r_[0,difx_d,0])
-        assert_equal(dx._mask, N.r_[1,0,0,0,0,1])
+        assert_equal(dx._data, np.r_[0,difx_d,0])
+        assert_equal(dx._mask, np.r_[1,0,0,0,0,1])
 
 class TestApplyAlongAxis(NumpyTestCase):
     "Tests 2D functions"

Modified: trunk/numpy/ma/tests/test_mrecords.py
===================================================================
--- trunk/numpy/ma/tests/test_mrecords.py	2008-06-08 18:10:55 UTC (rev 5263)
+++ trunk/numpy/ma/tests/test_mrecords.py	2008-06-08 23:04:42 UTC (rev 5264)
@@ -46,7 +46,8 @@
         "Test creation by view"
         base = self.base
         mbase = base.view(mrecarray)
-        assert_equal(mbase._mask, base._mask)
+        assert_equal(mbase.recordmask, base.recordmask)
+        assert_equal_records(mbase._mask, base._mask)
         assert isinstance(mbase._data, recarray)
         assert_equal_records(mbase._data, base._data.view(recarray))
         for field in ('a','b','c'):
@@ -66,14 +67,18 @@
         assert isinstance(mbase_first, mrecarray)
         assert_equal(mbase_first.dtype, mbase.dtype)
         assert_equal(mbase_first.tolist(), (1,1.1,'one'))
-        assert_equal(mbase_first.mask, nomask)
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_first.recordmask, nomask)
+        # _fieldmask and _mask should be the same thing
         assert_equal(mbase_first._fieldmask.item(), (False, False, False))
+        assert_equal(mbase_first._mask.item(), (False, False, False))
         assert_equal(mbase_first['a'], mbase['a'][0])
         mbase_last = mbase[-1]
         assert isinstance(mbase_last, mrecarray)
         assert_equal(mbase_last.dtype, mbase.dtype)
         assert_equal(mbase_last.tolist(), (None,None,None))
-        assert_equal(mbase_last.mask, True)
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_last.recordmask, True)
         assert_equal(mbase_last._fieldmask.item(), (True, True, True))
         assert_equal(mbase_last['a'], mbase['a'][-1])
         assert (mbase_last['a'] is masked)
@@ -81,7 +86,11 @@
         mbase_sl = mbase[:2]
         assert isinstance(mbase_sl, mrecarray)
         assert_equal(mbase_sl.dtype, mbase.dtype)
-        assert_equal(mbase_sl._mask, [0,1])
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_sl.recordmask, [0,1])
+        assert_equal_records(mbase_sl.mask,
+                             np.array([(False,False,False),(True,True,True)],
+                                      dtype=mbase._mask.dtype))
         assert_equal_records(mbase_sl, base[:2].view(mrecarray))
         for field in ('a','b','c'):
             assert_equal(getattr(mbase_sl,field), base[:2][field])
@@ -100,13 +109,16 @@
         mbase.a = 1
         assert_equal(mbase['a']._data, [1]*5)
         assert_equal(ma.getmaskarray(mbase['a']), [0]*5)
-        assert_equal(mbase._mask, [False]*5)
+        # Use to be _mask, now it's recordmask
+        assert_equal(mbase.recordmask, [False]*5)
         assert_equal(mbase._fieldmask.tolist(),
                      np.array([(0,0,0),(0,1,1),(0,0,0),(0,0,0),(0,1,1)],
                               dtype=bool))
         # Set a field to mask ........................
         mbase.c = masked
+        # Use to be mask, and now it's still mask !
         assert_equal(mbase.c.mask, [1]*5)
+        assert_equal(mbase.c.recordmask, [1]*5)
         assert_equal(ma.getmaskarray(mbase['c']), [1]*5)
         assert_equal(ma.getdata(mbase['c']), ['N/A']*5)
         assert_equal(mbase._fieldmask.tolist(),
@@ -201,10 +213,11 @@
         assert_equal(mbase._fieldmask.tolist(),
                      np.array([(0,0,0),(1,1,1),(0,0,0),(1,1,1),(1,1,1)],
                               dtype=bool))
-        assert_equal(mbase._mask, [0,1,0,1,1])
+        # Used to be mask, now it's recordmask!
+        assert_equal(mbase.recordmask, [0,1,0,1,1])
         # Set slices .................................
         mbase = base.view(mrecarray).copy()
-        mbase[:2] = 5
+        mbase[:2] = (5,5,5)
         assert_equal(mbase.a._data, [5,5,3,4,5])
         assert_equal(mbase.a._mask, [0,0,0,0,1])
         assert_equal(mbase.b._data, [5.,5.,3.3,4.4,5.5])
@@ -226,13 +239,29 @@
         base = self.base.copy()
         mbase = base.view(mrecarray)
         mbase.harden_mask()
-        mbase[-2:] = 5
-        assert_equal(mbase.a._data, [1,2,3,5,5])
-        assert_equal(mbase.b._data, [1.1,2.2,3.3,5,5.5])
-        assert_equal(mbase.c._data, ['one','two','three','5','five'])
-        assert_equal(mbase.a._mask, [0,1,0,0,1])
-        assert_equal(mbase.b._mask, mbase.a._mask)
-        assert_equal(mbase.b._mask, mbase.c._mask)
+        try:
+            mbase[-2:] = (5,5,5)
+            assert_equal(mbase.a._data, [1,2,3,5,5])
+            assert_equal(mbase.b._data, [1.1,2.2,3.3,5,5.5])
+            assert_equal(mbase.c._data, ['one','two','three','5','five'])
+            assert_equal(mbase.a._mask, [0,1,0,0,1])
+            assert_equal(mbase.b._mask, mbase.a._mask)
+            assert_equal(mbase.b._mask, mbase.c._mask)
+        except NotImplementedError:
+            # OK, not implemented yet...
+            pass
+        except AssertionError:
+            raise
+        else:
+            raise Exception("Flexible hard masks should be supported !")
+        # Not using a tuple should crash
+        try:
+            mbase[-2:] = 3
+        except (NotImplementedError, TypeError):
+            pass
+        else:
+            raise TypeError("Should have expected a readable buffer object!")
+            
 
     def test_hardmask(self):
         "Test hardmask"
@@ -241,11 +270,13 @@
         mbase.harden_mask()
         assert(mbase._hardmask)
         mbase._mask = nomask
-        assert_equal(mbase._mask, [0,1,0,0,1])
+        assert_equal_records(mbase._mask, base._mask)
         mbase.soften_mask()
         assert(not mbase._hardmask)
         mbase._mask = nomask
         # So, the mask of a field is no longer set to nomask...
+        assert_equal_records(mbase._mask, 
+                             ma.make_mask_none(base.shape,base.dtype.names))
         assert(ma.make_mask(mbase['b']._mask) is nomask)
         assert_equal(mbase['a']._mask,mbase['b']._mask)
     #



More information about the Numpy-svn mailing list