<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -15,7 +15,7 @@ but always 1-d) --- only has .copy and .__array__  attributes of an array!!!
 
 If you used typecode characters:
 
-'c' -&gt; 'S1'
+'c' -&gt; 'S1' or 'c'
 'b' -&gt; 'B'
 '1' -&gt; 'b'
 's' -&gt; 'h'
@@ -35,12 +35,12 @@ using PyMemData_FREE(ptr);
 a-&gt;descr-&gt;zero       --&gt;   PyArray_Zero(a)
 a-&gt;descr-&gt;one        --&gt;   PyArray_One(a)
 
-Numeric/arrayobject.h  --&gt;  numpy/arrayobject.h
+Numeric/arrayobject.h  --&gt;  numpy/oldnumeric.h
 
 
 # These will actually work and are defines for PyArray_BYTE, 
 #   but you really should change it in your code
-PyArray_CHAR         --&gt;  PyArray_BYTE  
+PyArray_CHAR         --&gt;  PyArray_CHAR  
    (or PyArray_STRING which is more flexible)  
 PyArray_SBYTE        --&gt;  PyArray_BYTE
 </diff>
      <filename>COMPATIBILITY</filename>
    </modified>
    <modified>
      <diff>@@ -12,7 +12,7 @@ __all__ = ['newaxis', 'ndarray', 'flatiter', 'ufunc',
            'array_repr', 'array_str', 'set_string_function',
            'little_endian', 'require',
            'fromiter', 'array_equal', 'array_equiv',
-           'indices', 'fromfunction',
+           'indices', 'fromfunction', 'loadtxt', 'savetxt',
            'load', 'loads', 'isscalar', 'binary_repr', 'base_repr',
            'ones', 'identity', 'allclose', 'compare_chararrays', 'putmask',
            'seterr', 'geterr', 'setbufsize', 'getbufsize',
@@ -610,6 +610,177 @@ def load(file):
         file = _file(file,&quot;rb&quot;)
     return _cload(file)
 
+# Adapted from matplotlib
+
+def _getconv(dtype):
+    typ = dtype.type
+    if issubclass(typ, bool_):
+        return lambda x: bool(int(x))
+    if issubclass(typ, integer):
+        return int
+    elif issubclass(typ, floating):
+        return float
+    elif issubclass(typ, complex):
+        return complex
+    else:
+        return str
+
+
+def _string_like(obj):
+    try: obj + ''
+    except (TypeError, ValueError): return 0
+    return 1
+
+def loadtxt(fname, dtype=float, comments='#', delimiter=None, converters=None,
+            skiprows=0, usecols=None, unpack=False):
+    &quot;&quot;&quot;
+    Load ASCII data from fname into an array and return the array.
+
+    The data must be regular, same number of values in every row
+
+    fname can be a filename or a file handle.  Support for gzipped files is
+    automatic, if the filename ends in .gz
+
+    See scipy.loadmat to read and write matfiles.
+
+    Example usage:
+
+      X = loadtxt('test.dat')  # data in two columns
+      t = X[:,0]
+      y = X[:,1]
+
+    Alternatively, you can do the same with &quot;unpack&quot;; see below
+
+      X = loadtxt('test.dat')    # a matrix of data
+      x = loadtxt('test.dat')    # a single column of data
+
+
+    dtype - the data-type of the resulting array.  If this is a
+    record data-type, the the resulting array will be 1-d and each row will
+    be interpreted as an element of the array. The number of columns
+    used must match the number of fields in the data-type in this case. 
+    
+    comments - the character used to indicate the start of a comment
+    in the file
+
+    delimiter is a string-like character used to seperate values in the
+    file. If delimiter is unspecified or none, any whitespace string is
+    a separator.
+
+    converters, if not None, is a dictionary mapping column number to
+    a function that will convert that column to a float.  Eg, if
+    column 0 is a date string: converters={0:datestr2num}
+
+    skiprows is the number of rows from the top to skip
+
+    usecols, if not None, is a sequence of integer column indexes to
+    extract where 0 is the first column, eg usecols=(1,4,5) to extract
+    just the 2nd, 5th and 6th columns
+
+    unpack, if True, will transpose the matrix allowing you to unpack
+    into named arguments on the left hand side
+
+        t,y = load('test.dat', unpack=True) # for  two column data
+        x,y,z = load('somefile.dat', usecols=(3,5,7), unpack=True)
+
+    &quot;&quot;&quot;
+
+    if _string_like(fname):
+        if fname.endswith('.gz'):
+            import gzip
+            fh = gzip.open(fname)
+        else:
+            fh = file(fname)
+    elif hasattr(fname, 'seek'):
+        fh = fname
+    else:
+        raise ValueError('fname must be a string or file handle')
+    X = []
+
+    dtype = multiarray.dtype(dtype)
+    defconv = _getconv(dtype)
+    converterseq = None    
+    if converters is None:
+        converters = {}
+        if dtype.names is not None:
+            converterseq = [_getconv(dtype.fields[name][0]) \
+                            for name in dtype.names]
+            
+    for i,line in enumerate(fh):
+        if i&lt;skiprows: continue
+        line = line[:line.find(comments)].strip()
+        if not len(line): continue
+        vals = line.split(delimiter)
+        if converterseq is None:
+           converterseq = [converters.get(j,defconv) \
+                           for j in xrange(len(vals))]
+        if usecols is not None:
+            row = [converterseq[j](vals[j]) for j in usecols]
+        else:
+            row = [converterseq[j](val) for j,val in enumerate(vals)]
+        if dtype.names is not None:
+            row = tuple(row)
+        X.append(row)
+
+    X = array(X, dtype)
+    r,c = X.shape
+    if r==1 or c==1:
+        X.shape = max([r,c]),
+    if unpack: return X.T
+    else:  return X
+
+
+# adjust so that fmt can change across columns if desired. 
+
+def savetxt(fname, X, fmt='%.18e',delimiter=' '):
+    &quot;&quot;&quot;
+    Save the data in X to file fname using fmt string to convert the
+    data to strings
+
+    fname can be a filename or a file handle.  If the filename ends in .gz,
+    the file is automatically saved in compressed gzip format.  The load()
+    command understands gzipped files transparently.
+
+    Example usage:
+
+    save('test.out', X)         # X is an array
+    save('test1.out', (x,y,z))  # x,y,z equal sized 1D arrays
+    save('test2.out', x)        # x is 1D
+    save('test3.out', x, fmt='%1.4e')  # use exponential notation
+
+    delimiter is used to separate the fields, eg delimiter ',' for
+    comma-separated values
+    &quot;&quot;&quot;
+
+    if _string_like(fname):
+        if fname.endswith('.gz'):
+            import gzip
+            fh = gzip.open(fname,'wb')
+        else:
+            fh = file(fname,'w')
+    elif hasattr(fname, 'seek'):
+        fh = fname
+    else:
+        raise ValueError('fname must be a string or file handle')
+
+
+    X = asarray(X)
+    origShape = None
+    if len(X.shape)==1:
+        origShape = X.shape
+        X.shape = len(X), 1
+    for row in X:
+        fh.write(delimiter.join([fmt%val for val in row]) + '\n')
+
+    if origShape is not None:
+        X.shape = origShape
+
+
+    
+
+
+
+
 # These are all essentially abbreviations
 # These might wind up in a special abbreviations module
 </diff>
      <filename>numpy/core/numeric.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>aba6f27ca5f699de521fbb1a1784b51006bba559</id>
    </parent>
  </parents>
  <author>
    <name>oliphant</name>
    <email>oliphant@94b884b6-d6fd-0310-90d3-974f1d3f35e1</email>
  </author>
  <url>http://github.com/cournape/numpy/commit/31d778a494341843f83951c854cb60567e641e91</url>
  <id>31d778a494341843f83951c854cb60567e641e91</id>
  <committed-date>2007-04-21T21:29:42-07:00</committed-date>
  <authored-date>2007-04-21T21:29:42-07:00</authored-date>
  <message>Add loadtxt and savetxt adapted from matplotlib.

git-svn-id: http://svn.scipy.org/svn/numpy/trunk@3722 94b884b6-d6fd-0310-90d3-974f1d3f35e1</message>
  <tree>c4ace75a4975175b5b2b4d12690c7d64be161799</tree>
  <committer>
    <name>oliphant</name>
    <email>oliphant@94b884b6-d6fd-0310-90d3-974f1d3f35e1</email>
  </committer>
</commit>
