Index: mercurial-howto.txt
===================================================================
--- mercurial-howto.txt	(revision 1268)
+++ mercurial-howto.txt	(revision 1268)
@@ -0,0 +1,152 @@
+IDENTITY:
+Make sure to define your username and password so the
+patches you make are identified as yours.  Make a 
+file ~/.hgrc like this
+
+[ui]
+username = William Stein <wstein@gmail.com>
+
+-----------------------------------------------------
+
+WARNING: Mercurial is much much different than darcs.
+ 
+You have to work with mercurial differently than with darcs.  It's
+crucial to create branches -- don't do everything in one place. With
+darcs that was possible, since darcs is so powerful, but with
+mercurial it's not.  (Indeed, I think that's just not how mercurial is
+designed to be used.)
+ 
+To make working with multiple branches very easy, I added a clone
+command to sage and improved how "sage -b" and "sage -br" work.
+ 
+QUICK MERCURIAL FOR SAGE (Tutorial)
+ 
+I assume you've upgraded SAGE to version 1.3.7.3.
+Mercurial is then available by default.   It's confusingly
+called hg (the chemical symbol for mercury) at the command line.
+Do "sage -hg" to run it, or make a link to SAGE_ROOT/local/bin/hg
+ 
+   1. LAYOUT CHANGE:
+      Now <SAGE_ROOT>/local/lib/python/site-packages/sage
+      is just a symlink to
+          <SAGE_ROOT>/devel/sage/build/sage
+      Thus by changing what <SAGE_ROOT>/devel/sage points to,
+      you can easily switch between running different versions of the
+      SAGE library.  The "sage -b" command does this automatically;
+      see below.
+ 
+   2. HOW TO CLONE:
+      If you type "sage -clone newver", say, then SAGE will use
+      hg to clone the current repository and call the result newver.
+      The new repository is stored in
+          <SAGE_ROOT>/devel/sage-newvar
+      and when you clone the symlink
+                   sage --> sage-newvar
+      is made.  Creating clones of a repository should be fairly fast,
+      e.g., about 30 seconds.  Most of the time is spent building
+      some pyrexembed code (and the need for this will vanish in
+      the future).
+      You can also do, e.g.,
+                 sage -clone -r 1250 oldvar
+      to get a clone of SAGE but as it was at revision 1250.   Thus you
+      can almost trivially go back in time.  Of course,
+      dependency issues could make old versions not work (e.g., old
+      SAGE won't compile with the latest singular library...).
+      Type "sage -hg log" while in the devel/sage-* directory, to see
+      the revision history.   NOTE - all the pyrex code is rebuilt
+      if you clone and old version, since there's no way for me to
+      easily know which files do and don't need rebuilding.
+ 
+   3. SWITCHING BRANCHES:
+      To switch to a different repository and build it, type, e.g.,
+                   sage -b newver
+      if the repository is stored in
+               <SAGE_ROOT>/devel/sage-newver
+ 
+   4. HG COMMAND:
+      You might want to make a symlink from
+               <SAGE_ROOT>/local/bin/hg
+      to something in your PATH.  Then you can type "hg <stuff>"
+      instead of "sage -hg <stuff>".
+ 
+   5. HOW TO USE:
+      Let's say you want to do a bunch of development, then make
+      it available.  Here's how:
+         (1) Make a new branch.
+         (2) Implement your functionality there.
+         (3) Type
+                  sage -hg diff [optional filenames] |more
+             to see exactly what you've done.
+             Type
+                  sage -hg status
+             to see which files have changed.
+         (4) Type "sage -hg add [optional filenames]" to add new
+             files to your repository.
+         (5) Type "sage -hg commit [optional filenames]" to commit
+             the changes in files to the
+             repository -- if not filenames are given all
+             files are commited.
+             NOTE -- here there is a huge difference from darcs!!!
+             You can't just commit bits and pieces of given files to a patch
+             like you can in darcs.   But you shouldn't have to since you're
+             only making changes relevant to this branch you cloaned, right.
+             Also, you *can* record different subsets of the files
+             to different
+             patches, so it's not so bad.
+         (6) Pull your changes back into your main repository:
+              cd <SAGE_ROOT>/devel/sage-main
+              sage -hg pull ../sage-my_other_branch
+              sage -hg update
+         (7) Send me *all* changes in the repository you're working in
+             as a bundle:
+ 
+sage -hg bundle mybundle.hg http://sage.math.washington.edu/sage/hg/sage-main
+ 
+             Note that you don't get to "cherry" pick what you
+             send me.   Everything
+             you recorded is sent.  Hence you might want to use the
+             cloning, etc.
+             above to send only from your own sage-main repository.
+             Note also that if you have a repository, e.g.,
+             sage-mynewstuff, you
+             and it's all ready to use, you can do
+               sage -hg pull <SAGE_ROOT>/devel/sage-mynewstuff
+             from your <SAGE_ROOT>/devel/sage-main repository, and you'll
+             get all the sage-mynewstuff merged in.   NOTE: read the output!
+             You must type "sage -hg update".
+ 
+         (8) You can also make a server with your repository:
+              sage -hg serve -p 9010   # or some other port.
+             Note that this doesn't print anything out till you hit it.
+             It provides a nice GUI way to browse your repository.
+             Anybody can pull from it...
+ 
+To emphasize -- if you try to use Mercurial as a "clone of darcs", you'll
+get frustrated and confused -- Mercurial works a bit more like svn
+or bizaare-ng or git than like darcs.  It is *very* different than darcs.
+But, it is a fairly simple (mostly) python program, and it is often
+*SHOCKINGLY* fast given what it is doing.  Also, so far it seems to me
+to be extremely robust and works well even with huge data sets.  It's a
+solid piece of quality software.
+ 
+Finally -- if you have some darcs patches you haven't given me yet, don't
+worry.  I have a SAGE's darcs --> mercurial patch conversion system setup
+on my laptop, so I can convert them.  Alternatively (better), merge the
+changes manually into your new mercurial repository and send me
+the bundle.
+ 
+Also, there's no analogue of the darcs_* Python functions yet.
+ 
+By the way, you can browse the official repositories for SAGE with your
+web browser here:
+    http://sage.math.washington.edu/sage/hg
+ 
+Another big change is that *all* the mercurial repositories related to
+SAGE are included with SAGE now by default.   Thus the complete change
+history and setup for doing development is there by default.  It's
+not something that has to be confusingly installed later.  This is reasaonble,
+partly because Mercurial is space efficient.  E.g., it adds only 5.6MB to
+the entire sage library right now (darcs added 20MB).
+ 
+ 
+   -- William
Index: sage/ext/sage_object.pyx
===================================================================
--- sage/ext/sage_object.pyx	(revision 985)
+++ sage/ext/sage_object.pyx	(revision 1270)
@@ -446,4 +446,11 @@
     have an .sobj extension added if it doesn't have one.
 
+    NOTE: There is also a special SAGE command (that is not
+    available in Python) called load that you use by typing
+                sage.: load filename.sage
+    The documentation below is not for that command.  The documentation
+    for load is almost identical to that for attach.  Type attach? for
+    help on attach.
+
     This also loads a ".sobj" file over a network by specifying the full URL.
     (Setting "verbose = False" suppresses the loading progress indicator.)    
Index: sage/misc/all.py
===================================================================
--- sage/misc/all.py	(revision 1217)
+++ sage/misc/all.py	(revision 1270)
@@ -7,4 +7,6 @@
                   DOT_SAGE, SAGE_ROOT, SAGE_URL, SAGE_DB, SAGE_TMP,
                   is_32_bit, is_64_bit, newton_method_sizes)
+
+from attach import attach
 
 from profiler import Profiler
Index: sage/misc/attach.py
===================================================================
--- sage/misc/attach.py	(revision 1270)
+++ sage/misc/attach.py	(revision 1270)
@@ -0,0 +1,41 @@
+class Attach:
+    r"""
+    Attach a file to a running instance of SAGE.
+
+    attach is *not* a function and is not part of the Python language.
+    You attach a file, e.g., foo.sage or foo.py or foo.spyx, to a
+    running SAGE session by typing
+    
+        sage.: attach foo.sage   # or foo.py   or foo.spyx
+
+    The contents of the file are then loaded, which means they are
+    read into the running SAGE session.  For example, if foo.sage
+    contains 'x=5', after attaching foo.sage the variable x will be
+    set to 5.  Moreover, any time you change foo.sage, the attached
+    file will be re-read automatically (with no intervention on your
+    part).
+
+    INPUT: attach file1 file2 ...
+        -- space-separated list of .py, .spyx, and .sage files.
+
+    EFFECT:
+        -- Each file is read in and added to an internal list of watched files.
+           The meaning of reading a file in depends on the file type:
+               .py   -- read in with no preparsing (so, e.g., 2^3 is 2 bit-or 3),
+               .sage -- preparsed then the result is read in
+               .spyx -- *not* preparsed.  Compiled to a module m then "from m import *"
+                        is executed.
+
+    Type \code{attached_files()} for a list of all currently attached files.
+    You can remove files from this list to stop them from being watched. 
+
+    NOTE: attach is exactly the same as load, except it keeps track of the
+    loaded file and automatically reloads it when it changes. 
+    """
+    def __repr__(self):
+        return self.__doc__
+
+    def __call__(self, *args, **kwds):
+        raise RuntimeError, "Use 'attach filename' instead, where filename is a .py, .sage, or .spyx file."
+
+attach = Attach()
Index: sage/misc/interpreter.py
===================================================================
--- sage/misc/interpreter.py	(revision 1173)
+++ sage/misc/interpreter.py	(revision 1267)
@@ -179,8 +179,11 @@
                     elif F[-5:] == '.sage':
                         ipmagic('run -i "%s"'%process_file(F))
-                    else:
+                    elif F[-5:] == '.spyx':
                         X = load_pyrex(F)
                         __IPYTHON__.push(X)
-                    
+                    else:
+                        print "Loading of '%s' not implemented (load .py, .spyx, and .sage files)"%F
+                        line = ''
+                        raise IOError
                     t = os.path.getmtime(F)                    
                     attached[F] = t
@@ -222,5 +225,5 @@
         except IOError:
             raise ImportError, 'Could not open file "%s"'%name
-
+        
         print 'Interactively loading "%s"'%name
         n = len(__IPYTHON__.input_hist)
@@ -256,5 +259,7 @@
             name = line[5:].strip()
         if isinstance(name, str):
-            if name[-3:] == '.py':
+            if not os.path.exists(name):
+                raise ImportError, "File '%s' not found (be sure to give .sage, .py, or .spyx extension)"%name
+            elif name[-3:] == '.py':
                 try:
                     line = '%run -i "' + name + '"'
@@ -272,11 +277,6 @@
                 line = load_pyrex(name)
             else:
-                try:
-                    line = '%run -i "' + name + '"'
-                except IOError, s:
-                    print s
-                    raise ImportError, "Maybe file '%s' does not exist"%name
-                    line = ""
-                    
+                raise ImportError, "Loading of '%s' not implemented (load .py, .spyx, and .sage files)"%name
+                line = ''
 
     elif line[:13] == 'save_session(':
@@ -313,5 +313,5 @@
         name = os.path.abspath(name)
         if not os.path.exists(name):
-            raise ImportError, "File '%s' not found."%name
+            raise ImportError, "File '%s' not found  (be sure to give .sage, .py, or .spyx extension)."%name
         elif name[-3:] == '.py':
             try:
@@ -334,5 +334,5 @@
                 line = ''
         else:
-            raise ImportError, "load: file (=%s) must have extension .py, .sage or .spyx"%name
+            raise ImportError, "Attaching of '%s' not implemented (load .py, .spyx, and .sage files)"%name
     if len(line) > 0:
         line = preparser_ipython.preparse_ipython(line)
Index: sage/misc/preparser.py
===================================================================
--- sage/misc/preparser.py	(revision 1100)
+++ sage/misc/preparser.py	(revision 1267)
@@ -306,8 +306,8 @@
 
         if magic and L[:5] == "load ":
-            #try:
-            name_load = str(eval(L[5:]))
-            #except:
-            #    name_load = L[5:].strip()
+            try:
+                name_load = str(eval(L[5:]))
+            except:
+                name_load = L[5:].strip()
             if name_load in loaded_files:
                 i += 1
@@ -327,7 +327,11 @@
                     A = A[:i] + G.readlines() + A[i+1:]
                     continue
-            else:
+            elif name_load[-5:] == '.spyx':
                 import interpreter
                 L = interpreter.load_pyrex(name_load)
+            else:
+                print "Loading of '%s' not implemented (load .py, .spyx, and .sage files)"%name_load
+                L = ''
+                continue
         M = preparse(L, reset=(i==0), do_time=do_time, ignore_prompts=ignore_prompts)
         F.append(M)
Index: sage/rings/all.py
===================================================================
--- sage/rings/all.py	(revision 1137)
+++ sage/rings/all.py	(revision 1271)
@@ -85,4 +85,6 @@
 Complexes = ComplexField
 
+from complex_double import ComplexDoubleField, ComplexDoubleElement, CDF
+
 # Univariate Polynomial Rings
 from polynomial_ring import PolynomialRing, polygen, is_PolynomialRing
Index: sage/rings/complex_double.pyx
===================================================================
--- sage/rings/complex_double.pyx	(revision 1271)
+++ sage/rings/complex_double.pyx	(revision 1271)
@@ -0,0 +1,361 @@
+include '../ext/cdefs.pxi'
+include '../ext/interrupt.pxi'
+include '../gsl/gsl_complex.pxi'
+
+import operator
+
+from sage.misc.sage_eval import sage_eval
+
+cimport sage.ext.element
+import sage.ext.element
+
+cimport sage.ext.ring
+import sage.ext.ring
+
+import complex_number
+
+
+cdef class ComplexDoubleField_class(sage.ext.ring.Field):
+    """
+    The field of complex double precision numbers.
+
+    ALGORITHM: Arithmetic is done using GSL (the GNU Scientific Library).
+    """
+
+    def __cmp__(self, other):
+        """
+        Returns True if and only if other is the unique complex double field.
+
+        EXAMPLES:
+            sage: CC == CDF
+            False
+            sage: CDF == ComplexDoubleField     # CDF is the shorthand
+            True
+        """
+        if other is ComplexDoubleField:
+            return 0
+        return -1
+
+    def __repr__(self):
+        """
+        Print out this complex double field.
+
+        EXAMPLES:
+            sage: ComplexDoubleField
+            Complex Double Field
+            sage: CDF
+            Complex Double Field
+        """
+        return "Complex Double Field"
+    
+    def __call__(self, x, im=None):
+        """
+        Create a complex double using x and optionally an imaginary part im.
+        
+        EXAMPLES:
+            sage: CDF(0,1)
+            1.0*I
+            sage: CDF(2/3)
+            0.666666666667
+            sage: CDF(5)
+            5.0
+            sage: CDF('i')
+            1.0*I
+            sage: CDF(complex(2,-3))
+            2.0 - 3.0*I
+            sage: CDF(4.5)
+            4.5
+            sage: CDF(1+I)
+            1.0 + 1.0*I
+
+        A TypeError is raised if the coercion doesn't make sense:
+            sage: CDF(QQ['x'].0)
+            Traceback (most recent call last):
+            ...
+            TypeError: cannot coerce nonconstant polynomial to float
+
+        One can convert back and forth between double precision complex
+        numbers and higher-precision ones, though of course there may
+        be loss of precision:
+            sage: a = ComplexField(200)(-2).sqrt(); a
+            1.4142135623730950488016887242096980785696718753769480731766796*I
+            sage: b = CDF(a); b
+            1.41421353817*I
+            sage: a.parent()(b)
+            1.4142135623700000000000000000000000000000000000000000000000002*I        
+        """
+        if im is None:
+            if isinstance(x, ComplexDoubleElement):
+                return x
+            elif isinstance(x, (float, int, long)):
+                return ComplexDoubleElement(x, 0)
+            elif isinstance(x, complex):
+                return ComplexDoubleElement(x.real, x.imag)
+            elif isinstance(x, complex_number.ComplexNumber):
+                return ComplexDoubleElement(x.real(), x.imag())
+            elif isinstance(x, str):
+                return sage_eval(x.replace(' ',''), locals={"I":self.gen(),"i":self.gen()})
+            else:
+                return ComplexDoubleElement(x, 0)
+        else:
+            return ComplexDoubleElement(x, im)
+
+    def gen(self, n=0):
+        """
+        Return the generator of the complex double field.
+        EXAMPLES:
+            sage: CDF.0
+            1.0*I
+            sage: CDF.gens()
+            (1.0*I,)
+        """
+        if n != 0:
+            raise ValueError, "only 1 generator"
+        return I
+
+    def ngens(self):
+        return 1
+
+cdef class ComplexDoubleElement(sage.ext.element.FieldElement):
+    cdef gsl_complex _complex
+    def __init__(self, real, imag):
+        self._complex = gsl_complex_rect(real, imag)
+
+    # TODO: real and imag should be elements of RealDoubleField, when that exists. 
+    def real(self):
+        """
+        Return the real part of this complex double.
+
+        EXAMPLES:
+            sage: a = CDF(3,-2)
+            sage: a.real()
+            3.0
+        """
+        return self._complex.dat[0]
+
+    def imag(self):
+        """
+        Return the imaginary part of this complex double.
+
+        EXAMPLES:
+            sage: a = CDF(3,-2)
+            sage: a.imag()
+            -2.0
+        """
+        return self._complex.dat[1]
+
+    def __complex__(self):
+        """
+        EXAMPLES:
+            sage: a = complex(2303,-3939)
+            sage: CDF(a)
+            2303.0 - 3939.0*I
+            sage: complex(CDF(a))
+            (2303-3939j)
+        """
+        return complex(self._complex.dat[0], self._complex.dat[1])
+
+    def parent(self):
+        """
+        Return the complex double field, which is the parent of self.
+
+        EXAMPLES:
+            sage: a = CDF(2,3)
+            sage: a.parent()
+            Complex Double Field
+            sage: parent(a)
+            Complex Double Field            
+        """
+        return CDF
+    
+    def __repr__(self):
+        """
+        Return print version of self.
+
+        EXAMPLES:
+            sage: a = CDF(2,-3); a
+            2.0 - 3.0*I
+            sage: a^2
+            -5.0 - 12.0*I
+        """
+        # todo -- redo completely in C
+        cdef float y
+        s = ""
+        if self._complex.dat[0] != 0:
+            s = str(self._complex.dat[0])
+        y  =  self._complex.dat[1]            
+        if y != 0:
+            if s != "":
+                if y < 0:
+                    s = s+" - "
+                    y = -y
+                else:
+                    s = s+" + "
+            s = s+"%s*I"%y
+        if len(s) == 0:
+            s = "0"
+        return s
+
+    def _add_(ComplexDoubleElement self, ComplexDoubleElement right):
+        """
+        Add self and right.
+
+        EXAMPLES:
+            sage: CDF(2,-3)._add_(CDF(1,-2))
+            3.0 - 5.0*I
+        """
+        cdef ComplexDoubleElement z
+        z = ComplexDoubleElement.__new__(ComplexDoubleElement)
+        z._complex = gsl_complex_add(self._complex, right._complex)
+        return z
+
+    def __add__(x, y):
+        try:
+            return x._add_(y)
+        except (TypeError, AttributeError):
+            return sage.rings.coerce.bin_op(x, y, operator.add)
+        #if isinstance(x, ComplexDoubleElement) and isinstance(y, ComplexDoubleElement):
+        #    return x._add_(y)
+        #return sage.rings.coerce.bin_op(x, y, operator.add)
+    
+    def _sub_(ComplexDoubleElement self, ComplexDoubleElement right):
+        """
+        Subtract self and right. 
+
+        EXAMPLES:
+            sage: CDF(2,-3)._sub_(CDF(1,-2))
+            1.0 - 1.0*I
+        """
+        cdef ComplexDoubleElement z
+        z = ComplexDoubleElement.__new__(ComplexDoubleElement)
+        z._complex = gsl_complex_sub(self._complex, right._complex)
+        return z
+
+    def __sub__(x, y):
+        try:
+            return x._sub_(y)
+        except (TypeError, AttributeError):
+            return sage.rings.coerce.bin_op(x, y, operator.sub)
+    
+    def _mul_(ComplexDoubleElement self, ComplexDoubleElement right):
+        """
+        Multiply self and right. 
+
+        EXAMPLES:
+            sage: CDF(2,-3)._mul_(CDF(1,-2))
+            -4.0 - 7.0*I
+        """
+        cdef ComplexDoubleElement z
+        z = ComplexDoubleElement.__new__(ComplexDoubleElement)
+        z._complex = gsl_complex_mul(self._complex, right._complex)
+        return z
+
+    def __mul__(x, y):
+        try:
+            return x._mul_(y)
+        except (TypeError, AttributeError):
+            return sage.rings.coerce.bin_op(x, y, operator.mul)
+
+    def _div_(ComplexDoubleElement self, ComplexDoubleElement right):
+        """
+        Divide self by right. 
+        
+        EXAMPLES:
+            sage: CDF(2,-3)._div_(CDF(1,-2))
+            1.6 + 0.20000000298*I
+        """
+        cdef ComplexDoubleElement z
+        z = ComplexDoubleElement.__new__(ComplexDoubleElement)
+        z._complex = gsl_complex_div(self._complex, right._complex)
+        return z
+
+    def __div__(x, y):
+        try:
+            return x._div_(y)
+        except (TypeError, AttributeError):
+            return sage.rings.coerce.bin_op(x, y, operator.div)
+
+    def arg(self):
+        r"""
+        This function returns the argument of the complex number $z$, $\arg(z)$,
+        where $-\pi < \arg(z) <= \pi$.
+
+        EXAMPLES:
+            sage: CDF(1,0).arg()
+            0.0
+            sage: CDF(0,1).arg()
+            1.5707963267948966
+            sage: CDF(0,-1).arg()
+            -1.5707963267948966
+            sage: CDF(-1,0).arg()
+            3.1415926535897931        
+        """
+        return gsl_complex_arg(self._complex)
+
+    def __abs__(self):
+        """
+        This function returns the magnitude of the complex number $z$, $|z|$.
+
+        EXAMPLES:
+            sage: abs(CDF(1,2))
+            2.2360679774997898
+            sage: abs(CDF(1,0))
+            1.0
+            sage: abs(CDF(-2,3))
+            3.6055512754639891        
+        """
+        return gsl_complex_abs(self._complex)
+
+    def abs(self):
+        """
+        This function returns the magnitude of the complex number $z$, $|z|$.
+
+        EXAMPLES:
+            sage: CDF(2,3).abs()
+            3.6055512754639891        
+        """
+        return gsl_complex_abs(self._complex)
+    
+    def abs2(self):
+        """
+        This function returns the squared magnitude of the complex number $z$, $|z|^2$.
+
+        EXAMPLES:
+            sage: CDF(2,3).abs2()
+            13.0        
+        """
+        return gsl_complex_abs2(self._complex)
+
+    def logabs(self):
+        r"""
+        This function returns the natural logarithm of the magnitude of the complex
+        number $z$, $\log|z|$.
+
+        This allows for an accurate evaluation of $\log|z| when $|z|$
+        is close to $1$.  The direct evaluation of \code{log(abs(z))}
+        would lead to a loss of precision in this case.
+
+        EXAMPLES:
+        We try it out. 
+            sage: CDF(1.1,0.1).logabs()
+            0.099425429372582669
+            sage: log(abs(CDF(1.1,0.1)))
+            0.099425429373735899
+
+        Which is better?  
+            sage: log(abs(ComplexField(200)(1.1,0.1)))
+            0.099425429372582675602989386713555936556752871164033127857197658
+
+        Indeed, the logabs, wins.            
+        """
+        return gsl_complex_logabs(self._complex)
+
+    
+
+#####################################################
+# unique objects
+#####################################################
+ComplexDoubleField = ComplexDoubleField_class()
+CDF = ComplexDoubleField
+I = ComplexDoubleElement(0,1)
+
Index: sage/rings/complex_field.py
===================================================================
--- sage/rings/complex_field.py	(revision 1097)
+++ sage/rings/complex_field.py	(revision 1271)
@@ -15,4 +15,5 @@
 
 import complex_number
+import complex_double
 import field
 import real_field
@@ -136,11 +137,14 @@
             2.0000000000000000 + 3.0000000000000000*I
         """
-        if isinstance(x, complex_number.ComplexNumber) and x.parent() == self:
-            return x
-        if isinstance(x, str) and im==None:
-            # TODO: this is probably not the best and most
-            # efficient way to do this.  -- Martin Albrecht
-            return complex_number.ComplexNumber(self,
-                        sage_eval(x.replace(' ',''), locals={"I":self.gen(),"i":self.gen()}))
+        if im is None:
+            if isinstance(x, complex_number.ComplexNumber) and x.parent() is self:
+                return x
+            elif isinstance(x, complex_double.ComplexDoubleElement):
+                return complex_number.ComplexNumber(self, x.real(), x.imag())
+            elif isinstance(x, str):
+                # TODO: this is probably not the best and most
+                # efficient way to do this.  -- Martin Albrecht
+                return complex_number.ComplexNumber(self,
+                            sage_eval(x.replace(' ',''), locals={"I":self.gen(),"i":self.gen()}))
         return complex_number.ComplexNumber(self, x, im)
 
Index: sage/rings/polynomial_element.py
===================================================================
--- sage/rings/polynomial_element.py	(revision 1153)
+++ sage/rings/polynomial_element.py	(revision 1269)
@@ -82,4 +82,8 @@
     Polynomial base class.
     """
+    def __new__(cls, *args, **kwds):
+        return ring_element.RingElement.__new__(*args, **kwds)
+    __new__ = classmethod(__new__)
+    
     def __init__(self, parent, is_gen = False, construct=False): 
         """
Index: setup.py
===================================================================
--- setup.py	(revision 1251)
+++ setup.py	(revision 1271)
@@ -164,4 +164,8 @@
                 libraries = ['gsl', CBLAS])
 
+complex_double = Extension('sage.rings.complex_double',
+                           ['sage/rings/complex_double.pyx'],
+                           libraries = ['gsl', CBLAS])
+
 #####################################################
 
@@ -191,4 +195,5 @@
     gsl_interpolation,
     gsl_callback,
+    complex_double,
 
     # complex_number2, \
