Exemplo n.º 1
0
 def __init__(self, cntrl, uknots, vknots):
     self._bezier = None
     cntrl = numerix.asarray(cntrl, numerix.Float)
     (dim, nu, nv) = cntrl.shape
     if dim < 2 or dim > 4:
         raise NURBSError, 'Illegal control point format'
     elif dim < 4:
         self.cntrl = numerix.zeros((4, nu, nv), numerix.Float)
         self.cntrl[0:dim,:,:] = cntrl
         self.cntrl[-1,:,:] = numerix.ones((nu,nv), numerix.Float)
     else:
         self.cntrl = cntrl
         
     # Force the u knot sequence to be a vector in ascending order
     # and normalise between [0.0,1.0]
     uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
     nku = uknots.shape[0]
     uknots = (uknots - uknots[0])/(uknots[-1] - uknots[0])
     if uknots[0] == uknots[-1]:
         raise NURBSError, 'Illegal uknots sequence'
     self.uknots = uknots
     
     # Force the v knot sequence to be a vector in ascending order
     # and normalise between [0.0,1.0]  
     vknots = -numerix.sort(-numerix.asarray(vknots, numerix.Float))
     nkv = vknots.shape[0]
     vknots = (vknots - vknots[0])/(vknots[-1] - vknots[0])
     if vknots[0] == vknots[-1]:
         raise NURBSError, 'Illegal vknots sequence'
     self.vknots = vknots
     
     # Spline Degree
     self.degree = [nku-nu-1, nkv-nv-1]
     if self.degree[0] < 0 or self.degree[1] < 0:
         raise NURBSError, 'NURBS order must be a positive integer'
Exemplo n.º 2
0
    def __init__(self, cntrl, uknots, vknots):
        self._bezier = None
        cntrl = numerix.asarray(cntrl, numerix.Float)
        (dim, nu, nv) = cntrl.shape
        if dim < 2 or dim > 4:
            raise NURBSError, 'Illegal control point format'
        elif dim < 4:
            self.cntrl = numerix.zeros((4, nu, nv), numerix.Float)
            self.cntrl[0:dim, :, :] = cntrl
            self.cntrl[-1, :, :] = numerix.ones((nu, nv), numerix.Float)
        else:
            self.cntrl = cntrl

        # Force the u knot sequence to be a vector in ascending order
        # and normalise between [0.0,1.0]
        uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
        nku = uknots.shape[0]
        uknots = (uknots - uknots[0]) / (uknots[-1] - uknots[0])
        if uknots[0] == uknots[-1]:
            raise NURBSError, 'Illegal uknots sequence'
        self.uknots = uknots

        # Force the v knot sequence to be a vector in ascending order
        # and normalise between [0.0,1.0]
        vknots = -numerix.sort(-numerix.asarray(vknots, numerix.Float))
        nkv = vknots.shape[0]
        vknots = (vknots - vknots[0]) / (vknots[-1] - vknots[0])
        if vknots[0] == vknots[-1]:
            raise NURBSError, 'Illegal vknots sequence'
        self.vknots = vknots

        # Spline Degree
        self.degree = [nku - nu - 1, nkv - nv - 1]
        if self.degree[0] < 0 or self.degree[1] < 0:
            raise NURBSError, 'NURBS order must be a positive integer'
Exemplo n.º 3
0
    def kntins(self, uknots, vknots=None):
        """Insert new knots into the surface
	uknots - knots to be inserted along u direction
	vknots - knots to be inserted along v direction
	NOTE: No knot multiplicity will be increased beyond the order of the spline"""
        if len(vknots):
            # Force the v knot sequence to be a vector in ascending order
            vknots = numerix.sort(numerix.asarray(vknots, numerix.Float))
            if numerix.any(vknots < 0.) or numerix.any(vknots > 1.):
                raise NURBSError, 'Illegal vknots sequence'
            coefs = numerix.resize(
                self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
            coefs, self.vknots = bspkntins(self.degree[1], coefs, self.vknots,
                                           vknots)
            self.cntrl = numerix.resize(
                coefs, (4, self.cntrl.shape[1], coefs.shape[1]))
        if len(uknots):
            # Force the u knot sequence to be a vector in ascending order
            uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
            if numerix.any(uknots < 0.) or numerix.any(uknots > 1.):
                raise NURBSError, 'Illegal uknots sequence'
            coefs = numerix.transpose(self.cntrl, (0, 2, 1))
            coefs = numerix.resize(
                coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1]))
            coefs, self.uknots = bspkntins(self.degree[0], coefs, self.uknots,
                                           uknots)
            coefs = numerix.resize(coefs,
                                   (4, self.cntrl.shape[2], coefs.shape[1]))
            self.cntrl = numerix.transpose(coefs, (0, 2, 1))
Exemplo n.º 4
0
 def bounds(self):
     "Return the bounding box for the surface."
     w = self.cntrl[3, :, :]
     cx = numerix.sort(numerix.ravel(self.cntrl[0, :, :] / w))
     cy = numerix.sort(numerix.ravel(self.cntrl[1, :, :] / w))
     cz = numerix.sort(numerix.ravel(self.cntrl[2, :, :] / w))
     return numerix.asarray([cx[0], cy[0], cz[0], cx[-1], cy[-1], cz[-1]],
                            numerix.Float)
Exemplo n.º 5
0
 def bounds(self):
     "Return the bounding box for the surface."
     w = self.cntrl[3,:,:]
     cx = numerix.sort(numerix.ravel(self.cntrl[0,:,:]/w))
     cy = numerix.sort(numerix.ravel(self.cntrl[1,:,:]/w))
     cz = numerix.sort(numerix.ravel(self.cntrl[2,:,:]/w))
     return numerix.asarray([cx[0], cy[0], cz[0],
                             cx[-1], cy[-1], cz[-1]], numerix.Float)
Exemplo n.º 6
0
def lowess2(x, y, xest, f=2./3., iter=3):
    """Returns estimated values of y in data points xest (or None if estimation fails).
    Lowess smoother: Robust locally weighted regression.
    The lowess function fits a nonparametric regression curve to a scatterplot.
    The arrays x and y contain an equal number of elements; each pair
    (x[i], y[i]) defines a data point in the scatterplot. The function returns
    the estimated (smooth) values of y.

    The smoothing span is given by f. A larger value for f will result in a
    smoother curve. The number of robustifying iterations is given by iter. The
    function will run faster with a smaller number of iterations."""
    x = Numeric.asarray(x, 'd')
    y = Numeric.asarray(y, 'd')
    xest = Numeric.asarray(xest, 'd')
    n = len(x)
    nest = len(xest)
    r = min(int(Numeric.ceil(f*n)),n-1) # radius: num. of points to take into LR
    h = [Numeric.sort(abs(x-x[i]))[r] for i in range(n)]    # distance of the r-th point from x[i]
    w = Numeric.clip(abs(([x]-Numeric.transpose([x]))/h),0.0,1.0)
    w = 1-w*w*w
    w = w*w*w
    hest = [Numeric.sort(abs(x-xest[i]))[r] for i in range(nest)]    # r-th min. distance from xest[i] to x
    west = Numeric.clip(abs(([xest]-Numeric.transpose([x]))/hest),0.0,1.0)  # shape: (len(x), len(xest)
    west = 1-west*west*west
    west = west*west*west
    yest = Numeric.zeros(n,'d')
    yest2 = Numeric.zeros(nest,'d')
    delta = Numeric.ones(n,'d')
    try:
        for iteration in range(iter):
            # fit xest
            for i in range(nest):
                weights = delta * west[:,i]
                b = Numeric.array([sum(weights*y), sum(weights*y*x)])
                A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]])
                beta = LinearAlgebra.solve_linear_equations(A,b)
                yest2[i] = beta[0] + beta[1]*xest[i]
            # fit x (to calculate residuals and delta)
            for i in range(n):
                weights = delta * w[:,i]
                b = Numeric.array([sum(weights*y), sum(weights*y*x)])
                A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]])
                beta = LinearAlgebra.solve_linear_equations(A,b)
                yest[i] = beta[0] + beta[1]*x[i]
            residuals = y-yest
            s = MLab.median(abs(residuals))
            delta = Numeric.clip(residuals/(6*s),-1,1)
            delta = 1-delta*delta
            delta = delta*delta
    except LinearAlgebra.LinAlgError:
        print "Warning: NumExtn.lowess2: LinearAlgebra.solve_linear_equations: Singular matrix"
        yest2 = None
    return yest2
Exemplo n.º 7
0
    def __init__(self, traj=None, recChains=[0], n_members=10, rec=None):
        """
        Use::
           ComplexTraj( traj, recChains=[0], n_members=10 )
        
        @param traj: Trajectory (default: 0)
        @type  traj: Trajectory
        @param recChains: list of chain indices defining receptor
                          (default: [0])
        @type  recChains: [int]
        @param n_members: number of ensemble members (for multi-copy MD)
                          (default: 10)
        @type  n_members: int
        @param rec: instead of using recChains, autodetect rec chains
                    by comparing traj.ref with the model given as rec
                    (default: None)
        @type  rec: PDBModel
        """
        EnsembleTraj.__init__( self )

        if traj:
            self.__dict__.update( traj.__dict__ )

            if rec:
                self.cr = self.ref.compareChains( rec )[0]
            else:
                self.cr = N.sort( recChains ).tolist()

            self.cl = range( 0, self.getRef().lenChains() )
            for c in self.cr:
                self.cl.remove(c)

        else:
            self.cr = self.cl = None
Exemplo n.º 8
0
    def kntins(self, uknots):
        """Insert new knots into the curve
	NOTE: No knot multiplicity will be increased beyond the order of the spline"""
        if len(uknots):
            uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
            if numerix.any(uknots < 0.) or numerix.any(uknots > 1.):
                raise NURBSError, 'NURBS curve parameter out of range [0,1]'
            self.cntrl, self.uknots = bspkntins(self.degree, self.cntrl, self.uknots, uknots)
Exemplo n.º 9
0
 def bounds(self):
     "Return the boundingbox for the curve"
     ww = numerix.resize(self.cntrl[-1, :], (3, self.cntrl.shape[1]))
     cntrl = numerix.sort(self.cntrl[0:3, :] / ww)
     return numerix.asarray([
         cntrl[0, 0], cntrl[1, 0], cntrl[2, 0], cntrl[0, -1], cntrl[1, -1],
         cntrl[2, -1]
     ], numerix.Float)
Exemplo n.º 10
0
    def kntins(self, uknots):
        """Insert new knots into the curve
	NOTE: No knot multiplicity will be increased beyond the order of the spline"""
        if len(uknots):
            uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
            if numerix.any(uknots < 0.) or numerix.any(uknots > 1.):
                raise NURBSError, 'NURBS curve parameter out of range [0,1]'
            self.cntrl, self.uknots = bspkntins(self.degree, self.cntrl,
                                                self.uknots, uknots)
Exemplo n.º 11
0
    def kntins(self, uknots, vknots = None):
        """Insert new knots into the surface
	uknots - knots to be inserted along u direction
	vknots - knots to be inserted along v direction
	NOTE: No knot multiplicity will be increased beyond the order of the spline"""
        if len(vknots):
            # Force the v knot sequence to be a vector in ascending order
            vknots = numerix.sort(numerix.asarray(vknots, numerix.Float))
            if numerix.any(vknots < 0.) or numerix.any(vknots > 1.):
                raise NURBSError, 'Illegal vknots sequence'
            coefs = numerix.resize(self.cntrl,(4*self.cntrl.shape[1], self.cntrl.shape[2]))
            coefs, self.vknots = bspkntins(self.degree[1], coefs, self.vknots, vknots)
            self.cntrl = numerix.resize(coefs, (4, self.cntrl.shape[1], coefs.shape[1]))
        if len(uknots):
            # Force the u knot sequence to be a vector in ascending order
            uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
            if numerix.any(uknots < 0.) or numerix.any(uknots > 1.):
                raise NURBSError, 'Illegal uknots sequence'
            coefs = numerix.transpose(self.cntrl,(0, 2, 1))
            coefs = numerix.resize(coefs,(4*self.cntrl.shape[2], self.cntrl.shape[1]))
            coefs, self.uknots = bspkntins(self.degree[0], coefs, self.uknots, uknots)
            coefs = numerix.resize(coefs, (4, self.cntrl.shape[2], coefs.shape[1]))
            self.cntrl = numerix.transpose(coefs,(0,2,1))
Exemplo n.º 12
0
 def drawLines(self):
     # angle has to be provided in radians
     angle = self.angle
         
     self.circlePtsAngles = self.circlePtsAngles+angle
     self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles,
                                              2*math.pi)
     xcoords = Numeric.cos(self.circlePtsAngles)
     xsin = Numeric.sin(self.circlePtsAngles)
     if self.orient=='horizontal':
         w = self.innerbox[2] - self.innerbox[0]
         r = w/2
         c = self.innerbox[0] + r
         y1 = self.innerbox[1]
         y2 = self.innerbox[3]
     else:
         w = self.innerbox[3] - self.innerbox[1]
         r = w/2
         c = self.innerbox[1] + r
         y1 = self.innerbox[0]
         y2 = self.innerbox[2]
         
     cl = self.canvas.create_line
     setCoords = self.canvas.coords
     setOpt = self.canvas.itemconfigure
     pi2 = math.pi/2.
     drawLines = 0
     co = Numeric.take(xcoords,
                       Numeric.nonzero(Numeric.greater_equal(xsin, 0.0)))
     co = Numeric.sort(co)
     co = [-1]+list(co)
     for i in range(len(co)):
         x = c - int(co[i]*r)
         if self.orient=='horizontal':
             setCoords(self.linesIds[i], x, y1, x, y2)
         else:
             setCoords(self.linesIds[i], y1, x, y2, x)
         shopt = self.shadowLinesOptions[i]
         x = x + shopt[0]
         if self.orient=='horizontal':
             setCoords(self.shLinesIds[i], x, y1, x, y2)
         else:
             setCoords(self.shLinesIds[i], y1, x, y2, x)
         setOpt(self.shLinesIds[i], fill = shopt[1], width=shopt[2])
Exemplo n.º 13
0
    def drawLines(self):
        # angle has to be provided in radians
        angle = self.angle

        self.circlePtsAngles = self.circlePtsAngles + angle
        self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles,
                                                 2 * math.pi)
        xcoords = Numeric.cos(self.circlePtsAngles)
        xsin = Numeric.sin(self.circlePtsAngles)
        if self.orient == 'horizontal':
            w = self.innerbox[2] - self.innerbox[0]
            r = w / 2
            c = self.innerbox[0] + r
            y1 = self.innerbox[1]
            y2 = self.innerbox[3]
        else:
            w = self.innerbox[3] - self.innerbox[1]
            r = w / 2
            c = self.innerbox[1] + r
            y1 = self.innerbox[0]
            y2 = self.innerbox[2]

        cl = self.canvas.create_line
        setCoords = self.canvas.coords
        setOpt = self.canvas.itemconfigure
        pi2 = math.pi / 2.
        drawLines = 0
        co = Numeric.take(xcoords,
                          Numeric.nonzero(Numeric.greater_equal(xsin, 0.0)))
        co = Numeric.sort(co)
        co = [-1] + list(co)
        for i in range(len(co)):
            x = c - int(co[i] * r)
            if self.orient == 'horizontal':
                setCoords(self.linesIds[i], x, y1, x, y2)
            else:
                setCoords(self.linesIds[i], y1, x, y2, x)
            shopt = self.shadowLinesOptions[i]
            x = x + shopt[0]
            if self.orient == 'horizontal':
                setCoords(self.shLinesIds[i], x, y1, x, y2)
            else:
                setCoords(self.shLinesIds[i], y1, x, y2, x)
            setOpt(self.shLinesIds[i], fill=shopt[1], width=shopt[2])
Exemplo n.º 14
0
 def __init__(self, crv1, crv2):
     if not isinstance(crv1, Crv.Crv):
         raise NURBSError, 'Parameter crv1 not derived from Crv class!'
     if not isinstance(crv2, Crv.Crv):
         raise NURBSError, 'Parameter crv2 not derived from Crv class!'
     # ensure both curves have a common degree
     d = max(crv1.degree, crv2.degree)
     crv1.degelev(d - crv1.degree)
     crv2.degelev(d - crv2.degree)
     # merge the knot vectors, to obtain a common knot vector
     k1 = crv1.uknots
     k2 = crv2.uknots
     ku = []
     for item in k1:
         if not numerix.sometrue(numerix.equal(k2, item)):
             if item not in ku:
                 ku.append(item)
     for item in k2:
         if not numerix.sometrue(numerix.equal(k1, item)):
             if item not in ku:
                 ku.append(item)
     ku = numerix.sort(numerix.asarray(ku, numerix.Float))
     n = ku.shape[0]
     ka = numerix.array([], numerix.Float)
     kb = numerix.array([], numerix.Float)
     for i in range(0, n):
         i1 = numerix.compress(numerix.equal(k1, ku[i]), k1).shape[0]
         i2 = numerix.compress(numerix.equal(k2, ku[i]), k2).shape[0]
         m = max(i1, i2)
         ka = numerix.concatenate((ka, ku[i] * numerix.ones(
             (m - i1, ), numerix.Float)))
         kb = numerix.concatenate((kb, ku[i] * numerix.ones(
             (m - i2, ), numerix.Float)))
     crv1.kntins(ka)
     crv2.kntins(kb)
     coefs = numerix.zeros((4, crv1.cntrl.shape[1], 2), numerix.Float)
     coefs[:, :, 0] = crv1.cntrl
     coefs[:, :, 1] = crv2.cntrl
     Srf.__init__(self, coefs, crv1.uknots, [0., 0., 1., 1.])
Exemplo n.º 15
0
 def __init__(self, crv1, crv2):
     if not isinstance(crv1, Crv.Crv):
             raise NURBSError, 'Parameter crv1 not derived from Crv class!'
     if not isinstance(crv2, Crv.Crv):
             raise NURBSError, 'Parameter crv2 not derived from Crv class!'
     # ensure both curves have a common degree
     d = max(crv1.degree, crv2.degree)
     crv1.degelev(d - crv1.degree)
     crv2.degelev(d - crv2.degree)
     # merge the knot vectors, to obtain a common knot vector
     k1 = crv1.uknots
     k2 = crv2.uknots
     ku = []
     for item in k1:
         if not numerix.sometrue(numerix.equal(k2, item)):
             if item not in ku:
                 ku.append(item)
     for item in k2:
         if not numerix.sometrue(numerix.equal(k1, item)):
             if item not in ku:
                 ku.append(item)
     ku = numerix.sort(numerix.asarray(ku, numerix.Float))
     n = ku.shape[0]
     ka = numerix.array([], numerix.Float)
     kb = numerix.array([], numerix.Float)
     for i in range(0, n):
         i1 = numerix.compress(numerix.equal(k1, ku[i]), k1).shape[0]
         i2 = numerix.compress(numerix.equal(k2, ku[i]), k2).shape[0]
         m = max(i1, i2)
         ka = numerix.concatenate((ka , ku[i] * numerix.ones((m - i1,), numerix.Float)))
         kb = numerix.concatenate((kb , ku[i] * numerix.ones((m - i2,), numerix.Float)))
     crv1.kntins(ka)
     crv2.kntins(kb)
     coefs = numerix.zeros((4, crv1.cntrl.shape[1], 2), numerix.Float)
     coefs[:,:,0] = crv1.cntrl
     coefs[:,:,1] = crv2.cntrl
     Srf.__init__(self, coefs, crv1.uknots, [0., 0., 1., 1.])
def wavenumber_integration(tb, wl, response):
    x = []
    y = []
    for i in range(len(wl)):
        x.append(1. / wl[i])
        #print "wavelength,wavenumber: ",wl[i],1./wl[i]
        yval_length = blackbody(wl[i], tb) * response[i] * (wl[i] * wl[i])
        yval = blackbody(1. / wl[i], tb, "wavenumber") * response[i]
        #print "YVAL: ",yval,yval_length
        y.append(yval)

    x = Numeric.array(x)
    y = Numeric.array(y)
    y = Numeric.choose(Numeric.argsort(x), y)
    x = Numeric.sort(x)

    response = Numeric.array(response)

    res = integral(x, y)
    # Normalisation:
    norm = integral(x, response)
    #print "Norm: ",norm

    return res / norm
Exemplo n.º 17
0
            n_one = 0
            while n_one < 21:
                one_sigma_mags = Numeric.compress(
                    Numeric.less_equal(abs(em[i, :] - 0.7526), dm), m[i, :])
                n_one = len(one_sigma_mags)
                dm += 0.01
                if dm > 0.03 and dm < 1.1:
                    message = "Warning: not enough 1-sigma objects in the catalog. Using dm=+-%.2f" % dm
                    self.logfile.write(message)
                if dm >= 1.1:
                    message = "Warning: Stopped searching for 1-sigma objects at dm=+-%.2f" % dm
                    self.logfile.write(message)
                    break

            try:
                limMag = MLab.median(Numeric.sort(one_sigma_mags)[-20:])
                self.logfile.write("Limiting Mag  " + basefits + ":" +
                                   str(limMag))
                print "Limiting Mag  " + basefits + ":" + str(limMag)
            except Exception, err:
                print "Exception raised: could not determine limiting magnitude."
                print err

            #---------------------- End  Limiting Magnitude Section ----------------------#

            #self.outColumns.append(imfilter +'_MAG_ISO')
            #self.outColumns.append(imfilter +'_MAGERR_ISO')
            self.outColumns.append(imfilter + '_MAGCORR_ISO')
            self.outColumns.append(imfilter + '_MAGERRCORR_ISO')
            self.outColumns.append(imfilter + '_APER_CORR')
            self.outColumns.append(imfilter + '_MAG_BPZ')
Exemplo n.º 18
0
def lowessW(x, y, xest, f=2./3., iter=3, dWeights=None, callback=None):
    """Returns estimated values of y in data points xest (or None if estimation fails).
    Lowess smoother: Robust locally weighted regression.
    The lowess function fits a nonparametric regression curve to a scatterplot.
    The arrays x and y contain an equal number of elements; each pair
    (x[i], y[i]) defines a data point in the scatterplot. The function returns
    the estimated (smooth) values of y.

    The smoothing span is given by f. A larger value for f will result in a
    smoother curve. The number of robustifying iterations is given by iter. The
    function will run faster with a smaller number of iterations.

    Data points may be assigned weights; if None, all weights equal 1.
    """
    x = Numeric.asarray(x, 'd')
    y = Numeric.asarray(y, 'd')
    xest = Numeric.asarray(xest, 'd')
    n = len(x)
    if n <> len(y):
        raise AttributeError, "Error: lowessW(x,y,xest,f,iter,dWeights): len(x)=%i not equal to len(y)=%i" % (len(x), len(y))
    nest = len(xest)
    # weights of data points (optional)
    if dWeights <> None:
        dWeights = Numeric.asarray(dWeights, 'd')
        if len(dWeights) <> n:
            raise AttributeError, "Error: lowessW(x,y,xest,f,iter,dWeights): len(dWeights)=%i not equal to len(x)=%i" % (len(dWeights), len(x))
##        dWeights = dWeights.reshape((n,1))
    else:
##        dWeights = Numeric.ones((n,1))
        dWeights = Numeric.ones((n,))
    r = min(int(Numeric.ceil(f*n)),n-1) # radius: num. of points to take into LR
    h = [Numeric.sort(abs(x-x[i]))[r] for i in range(n)]    # distance of the r-th point from x[i]
    w = Numeric.clip(abs(([x]-Numeric.transpose([x]))/h),0.0,1.0)
    w = 1-w*w*w
    w = w*w*w
    hest = [Numeric.sort(abs(x-xest[i]))[r] for i in range(nest)]    # r-th min. distance from xest[i] to x
    west = Numeric.clip(abs(([xest]-Numeric.transpose([x]))/hest),0.0,1.0)  # shape: (len(x), len(xest))
    west = 1-west*west*west
    west = west*west*west
    yest = Numeric.zeros(n,'d')
    yest2 = Numeric.zeros(nest,'d')
    delta = Numeric.ones(n,'d')
    try:
        for iteration in range(int(iter)):
            # fit xest
            for i in range(nest):
##                print delta.shape, west[:,i].shape, dWeights.shape
                weights = delta * west[:,i] * dWeights
                b = Numeric.array([sum(weights*y), sum(weights*y*x)])
                A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]])
                beta = LinearAlgebra.solve_linear_equations(A,b)
                yest2[i] = beta[0] + beta[1]*xest[i]
            # fit x (to calculate residuals and delta)
            for i in range(n):
                weights = delta * w[:,i] * dWeights
                b = Numeric.array([sum(weights*y), sum(weights*y*x)])
                A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]])
                beta = LinearAlgebra.solve_linear_equations(A,b)
                yest[i] = beta[0] + beta[1]*x[i]
            residuals = y-yest
            s = MLab.median(abs(residuals))
            delta = Numeric.clip(residuals/(6*s),-1,1)
            delta = 1-delta*delta
            delta = delta*delta
            if callback: callback()
    except LinearAlgebra.LinAlgError:
        print "Warning: NumExtn.lowessW: LinearAlgebra.solve_linear_equations: Singular matrix"
        yest2 = None
    return yest2
Exemplo n.º 19
0
    def __init__(self, u1, u2, v1, v2):
        if not isinstance(u1, Crv.Crv):
                raise NURBSError, 'Parameter u1 not derived from Crv class!'
        if not isinstance(u2, Crv.Crv):
                raise NURBSError, 'Parameter u2 not derived from Crv class!'
        if not isinstance(v1, Crv.Crv):
                raise NURBSError, 'Parameter v1 not derived from Crv class!'
        if not isinstance(v2, Crv.Crv):
                raise NURBSError, 'Parameter v2 not derived from Crv class!'
        r1 = Ruled(u1, u2)
        r2 = Ruled(v1, v2)
        r2.swapuv()
        t = Bilinear(u1.cntrl[:,0], u1.cntrl[:,-1], u2.cntrl[:,0], u2.cntrl[:,-1])
        # Raise all surfaces to a common degree
        du = max(r1.degree[0], r2.degree[0], t.degree[0])
        dv = max(r1.degree[1], r2.degree[1], t.degree[1])
        r1.degelev(du - r1.degree[0], dv - r1.degree[1])
        r2.degelev(du - r2.degree[0], dv - r2.degree[1])
        t.degelev(du - t.degree[0], dv - t.degree[1])
        # Merge the knot vectors, to obtain a common knot vector
        # uknots:
        k1 = r1.uknots
        k2 = r2.uknots
        k3 = t.uknots
        k = []
        for item in k1:
            if not numerix.sometrue(numerix.equal(k2, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k2:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k3:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k2, item)):
                    if item not in k:
                        k.append(item)        
        k = numerix.sort(numerix.asarray(k, numerix.Float))
        n = k.shape[0]
        kua = numerix.array([], numerix.Float)
        kub = numerix.array([], numerix.Float)
        kuc = numerix.array([], numerix.Float)
        for i in range(0, n):
            i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0]
            i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0]
            i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0]
            m = max(i1, i2, i3)
            kua = numerix.concatenate((kua , k[i] * numerix.ones((m - i1,), numerix.Float)))
            kub = numerix.concatenate((kub , k[i] * numerix.ones((m - i2,), numerix.Float)))
            kuc = numerix.concatenate((kuc , k[i] * numerix.ones((m - i3,), numerix.Float)))

        # vknots:
        k1 = r1.vknots
        k2 = r2.vknots
        k3 = t.vknots
        k = []
        for item in k1:
            if not numerix.sometrue(numerix.equal(k2, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k2:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k3:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k2, item)):
                    if item not in k:
                        k.append(item)        
        k = numerix.sort(numerix.asarray(k, numerix.Float))
        n = k.shape[0]
        kva = numerix.array([], numerix.Float)
        kvb = numerix.array([], numerix.Float)
        kvc = numerix.array([], numerix.Float)
        for i in range(0, n):
            i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0]
            i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0]
            i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0]
            m = max(i1, i2, i3)
            kva = numerix.concatenate((kva , k[i] * numerix.ones((m - i1,), numerix.Float)))
            kvb = numerix.concatenate((kvb , k[i] * numerix.ones((m - i2,), numerix.Float)))
            kvc = numerix.concatenate((kvc , k[i] * numerix.ones((m - i3,), numerix.Float)))

        r1.kntins(kua, kva)
        r2.kntins(kub, kvb)
        t.kntins(kuc, kvc)
        coefs = numerix.zeros((4 , t.cntrl.shape[1], t.cntrl.shape[2]), numerix.Float)
        coefs[0,:,:] = r1.cntrl[0,:,:] + r2.cntrl[0,:,:] - t.cntrl[0,:,:]
        coefs[1,:,:] = r1.cntrl[1,:,:] + r2.cntrl[1,:,:] - t.cntrl[1,:,:]
        coefs[2,:,:] = r1.cntrl[2,:,:] + r2.cntrl[2,:,:] - t.cntrl[2,:,:]
        coefs[3,:,:] = r1.cntrl[3,:,:] + r2.cntrl[3,:,:] - t.cntrl[3,:,:]
        Srf.__init__(self, coefs, r1.uknots, r1.vknots)
Exemplo n.º 20
0
 def bounds(self):
     "Return the boundingbox for the curve"
     ww = numerix.resize(self.cntrl[-1,:], (3, self.cntrl.shape[1]))
     cntrl = numerix.sort(self.cntrl[0:3,:]/ww)
     return numerix.asarray([cntrl[0,0], cntrl[1,0], cntrl[2,0],
                             cntrl[0,-1], cntrl[1,-1], cntrl[2,-1]], numerix.Float)
Exemplo n.º 21
0
    def pcMovie(self, ev, steps, factor=1., ref=0, morph=1):
        """
        Morph between the two extreme values of a single principal
        component.

        @param ev: EigenVector to visualize
        @type  ev: int
        @param steps: number of intermediate frames
        @type  steps: int
        @param factor: exageration factor (default: 1 = No exageration)
        @type  factor: float
        @param ref: take other eigenvecors from this frame (default: 1)
        @type  ref: int
        @param morph: morph between min and max (1) or take real values (0)
                      (default: 1)
        @type  morph: 1|0

        @return: Trajectory with frames visualizing the morphing.
        @rtype: Trajectory
        """
        fit = 1
        if self.pc is not None:
            fit = self.pc['fit']
        pc = self.getPca(fit=fit)

        ## eigenvectors (rows)
        U = pc['u']

        ## raveled and centered frames
        x_avg = N.average(self.frames, 0)
        X = N.array([N.ravel(x) for x in self.frames - x_avg])

        ## ev'th eigenvector of reference frame
        alpha_0 = N.dot(X[ref], U[ev])

        ## list of deviations of ev'th eigenvector of each frame from ref
        alpha_range = N.dot(X, U[ev]) - alpha_0

        ## get some representative alphas...
        if morph:
            a_min = factor * min(alpha_range)
            a_max = factor * max(alpha_range)
            delta = (a_max - a_min) / steps
            alpha_range = [a_min + i * (delta) for i in range(0, steps)]
        else:
            alpha_range = N.sort(alpha_range)
            delta = len(alpha_range) / (steps * 1.0)
            alpha_range = [
                alpha_range[int(round(i * delta))] for i in range(0, steps)
            ]

        ## scale ev'th eigenvector of ref with different alphas
        Y = N.array([X[ref] + alpha * U[ev] for alpha in alpha_range])

        ## back convert to N x 3 coordinates
        Y = N.reshape(Y, (Y.shape[0], -1, 3))
        Y = x_avg + Y

        result = self.__class__()
        result.ref = self.ref

        result.frames = Y
        return result
Exemplo n.º 22
0
    def __init__(self, u1, u2, v1, v2):
        if not isinstance(u1, Crv.Crv):
            raise NURBSError, 'Parameter u1 not derived from Crv class!'
        if not isinstance(u2, Crv.Crv):
            raise NURBSError, 'Parameter u2 not derived from Crv class!'
        if not isinstance(v1, Crv.Crv):
            raise NURBSError, 'Parameter v1 not derived from Crv class!'
        if not isinstance(v2, Crv.Crv):
            raise NURBSError, 'Parameter v2 not derived from Crv class!'
        r1 = Ruled(u1, u2)
        r2 = Ruled(v1, v2)
        r2.swapuv()
        t = Bilinear(u1.cntrl[:, 0], u1.cntrl[:, -1], u2.cntrl[:, 0],
                     u2.cntrl[:, -1])
        # Raise all surfaces to a common degree
        du = max(r1.degree[0], r2.degree[0], t.degree[0])
        dv = max(r1.degree[1], r2.degree[1], t.degree[1])
        r1.degelev(du - r1.degree[0], dv - r1.degree[1])
        r2.degelev(du - r2.degree[0], dv - r2.degree[1])
        t.degelev(du - t.degree[0], dv - t.degree[1])
        # Merge the knot vectors, to obtain a common knot vector
        # uknots:
        k1 = r1.uknots
        k2 = r2.uknots
        k3 = t.uknots
        k = []
        for item in k1:
            if not numerix.sometrue(numerix.equal(k2, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k2:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k3:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k2, item)):
                    if item not in k:
                        k.append(item)
        k = numerix.sort(numerix.asarray(k, numerix.Float))
        n = k.shape[0]
        kua = numerix.array([], numerix.Float)
        kub = numerix.array([], numerix.Float)
        kuc = numerix.array([], numerix.Float)
        for i in range(0, n):
            i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0]
            i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0]
            i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0]
            m = max(i1, i2, i3)
            kua = numerix.concatenate((kua, k[i] * numerix.ones(
                (m - i1, ), numerix.Float)))
            kub = numerix.concatenate((kub, k[i] * numerix.ones(
                (m - i2, ), numerix.Float)))
            kuc = numerix.concatenate((kuc, k[i] * numerix.ones(
                (m - i3, ), numerix.Float)))

        # vknots:
        k1 = r1.vknots
        k2 = r2.vknots
        k3 = t.vknots
        k = []
        for item in k1:
            if not numerix.sometrue(numerix.equal(k2, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k2:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k3, item)):
                    if item not in k:
                        k.append(item)
        for item in k3:
            if not numerix.sometrue(numerix.equal(k1, item)):
                if not numerix.sometrue(numerix.equal(k2, item)):
                    if item not in k:
                        k.append(item)
        k = numerix.sort(numerix.asarray(k, numerix.Float))
        n = k.shape[0]
        kva = numerix.array([], numerix.Float)
        kvb = numerix.array([], numerix.Float)
        kvc = numerix.array([], numerix.Float)
        for i in range(0, n):
            i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0]
            i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0]
            i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0]
            m = max(i1, i2, i3)
            kva = numerix.concatenate((kva, k[i] * numerix.ones(
                (m - i1, ), numerix.Float)))
            kvb = numerix.concatenate((kvb, k[i] * numerix.ones(
                (m - i2, ), numerix.Float)))
            kvc = numerix.concatenate((kvc, k[i] * numerix.ones(
                (m - i3, ), numerix.Float)))

        r1.kntins(kua, kva)
        r2.kntins(kub, kvb)
        t.kntins(kuc, kvc)
        coefs = numerix.zeros((4, t.cntrl.shape[1], t.cntrl.shape[2]),
                              numerix.Float)
        coefs[
            0, :, :] = r1.cntrl[0, :, :] + r2.cntrl[0, :, :] - t.cntrl[0, :, :]
        coefs[
            1, :, :] = r1.cntrl[1, :, :] + r2.cntrl[1, :, :] - t.cntrl[1, :, :]
        coefs[
            2, :, :] = r1.cntrl[2, :, :] + r2.cntrl[2, :, :] - t.cntrl[2, :, :]
        coefs[
            3, :, :] = r1.cntrl[3, :, :] + r2.cntrl[3, :, :] - t.cntrl[3, :, :]
        Srf.__init__(self, coefs, r1.uknots, r1.vknots)
Exemplo n.º 23
0
    def pcMovie( self, ev, steps, factor=1., ref=0, morph=1 ):
        """
        Morph between the two extreme values of a single principal
        component.

        @param ev: EigenVector to visualize
        @type  ev: int
        @param steps: number of intermediate frames
        @type  steps: int
        @param factor: exageration factor (default: 1 = No exageration)
        @type  factor: float
        @param ref: take other eigenvecors from this frame (default: 1)
        @type  ref: int
        @param morph: morph between min and max (1) or take real values (0)
                      (default: 1)
        @type  morph: 1|0

        @return: Trajectory with frames visualizing the morphing.
        @rtype: Trajectory
        """
        fit = 1
        if self.pc is not None:
            fit = self.pc['fit']
        pc = self.getPca( fit=fit )

        ## eigenvectors (rows)
        U = pc['u']

        ## raveled and centered frames
        x_avg = N.average(self.frames, 0)
        X = N.array( [N.ravel(x) for x in self.frames - x_avg] )

        ## ev'th eigenvector of reference frame
        alpha_0 = N.dot( X[ref], U[ev] )

        ## list of deviations of ev'th eigenvector of each frame from ref
        alpha_range = N.dot(X, U[ev]) - alpha_0

        ## get some representative alphas...
        if morph:
            a_min = factor * min(alpha_range)
            a_max = factor * max(alpha_range)
            delta = (a_max - a_min) / steps
            alpha_range = [ a_min + i*(delta) for i in range(0, steps) ]
        else:
            alpha_range = N.sort( alpha_range )
            delta = len(alpha_range) / (steps * 1.0)
            alpha_range = [ alpha_range[ int(round( i*delta )) ]
                            for i in range(0,steps) ]

        ## scale ev'th eigenvector of ref with different alphas 
        Y = N.array( [ X[ref] + alpha * U[ev] for alpha in alpha_range] )

        ## back convert to N x 3 coordinates
        Y = N.reshape(Y, (Y.shape[0], -1, 3))
        Y = x_avg + Y

        result = self.__class__()
        result.ref = self.ref

        result.frames = Y
        return result
Exemplo n.º 24
0
class Crv:
    '''Construct a NURB curve and check the format.
    
 The NURB curve is represented by a 4 dimensional b-spline.

 INPUT:

    cntrl  - Control points, homogeneous coordinates (wx,wy,wz,w)
            [dim,nu] matrix
            dim is the dimension valid options are:
            2 .... (x,y)        2D cartesian coordinates
            3 .... (x,y,z)      3D cartesian coordinates   
            4 .... (wx,wy,wz,w) 4D homogeneous coordinates

    uknots - Knot sequence along the parametric u direction.

 NOTES:

    Its assumed that the input knot sequences span the
    interval [0.0,1.0] and are clamped to the control
    points at the end by a knot multiplicity equal to
    the spline order.'''
    def __init__(self, cntrl, uknots):
        self._bezier = None
        # Force the u knot sequence to be a vector in ascending order
        # and normalise between [0.0,1.0]
        uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
        nku = uknots.shape[0]
        uknots = (uknots - uknots[0]) / (uknots[-1] - uknots[0])
        if uknots[0] == uknots[-1]:
            raise NURBSError, 'Illegal uknots sequence'
        self.uknots = uknots
        cntrl = numerix.asarray(cntrl, numerix.Float)
        (dim, nu) = cntrl.shape
        if dim < 2 or dim > 4:
            raise NURBSError, 'Illegal control point format'
        elif dim < 4:
            self.cntrl = numerix.zeros((4, nu), numerix.Float)
            self.cntrl[0:dim, :] = cntrl
            self.cntrl[-1, :] = numerix.ones((nu, ))
        else:
            self.cntrl = cntrl
        # Spline degree
        self.degree = nku - nu - 1
        if self.degree < 0:
            raise NURBSError, 'NURBS order must be a positive integer'

    def trans(self, mat):
        "Apply the 4D transform matrix to the NURB control points."
        self.cntrl = numerix.dot(mat, self.cntrl)

    def reverse(self):
        "Reverse evaluation direction"
        self.cntrl = self.cntrl[:, ::-1]
        self.uknots = 1 - self.uknots[::-1]

    def kntins(self, uknots):
        """Insert new knots into the curve
	NOTE: No knot multiplicity will be increased beyond the order of the spline"""
        if len(uknots):
            uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
            if numerix.any(uknots < 0.) or numerix.any(uknots > 1.):
                raise NURBSError, 'NURBS curve parameter out of range [0,1]'
            self.cntrl, self.uknots = bspkntins(self.degree, self.cntrl,
                                                self.uknots, uknots)

    def degelev(self, degree):
        "Degree elevate the curve"
        if degree < 0:
            raise NURBSError, 'degree must be a positive number'
        if degree > 0:
            cntrl, uknots, nh = bspdegelev(self.degree, self.cntrl,
                                           self.uknots, degree)
            self.cntrl = cntrl[:, :nh + 1]
            self.uknots = uknots[:nh + self.degree + degree + 2]
            self.degree += degree

    def bezier(self, update=None):
        "Decompose curve to bezier segments and return overlaping control points"
        if update or not self._bezier:
            self._bezier = bspbezdecom(self.degree, self.cntrl, self.uknots)
        return self._bezier

    def bounds(self):
        "Return the boundingbox for the curve"
        ww = numerix.resize(self.cntrl[-1, :], (3, self.cntrl.shape[1]))
        cntrl = numerix.sort(self.cntrl[0:3, :] / ww)
        return numerix.asarray([
            cntrl[0, 0], cntrl[1, 0], cntrl[2, 0], cntrl[0, -1], cntrl[1, -1],
            cntrl[2, -1]
        ], numerix.Float)

    def pnt3D(self, ut):
        "Evaluate parametric point[s] and return 3D cartesian coordinate[s]"
        val = self.pnt4D(ut)
        return val[0:3, :] / numerix.resize(val[-1, :], (3, val.shape[1]))

    def pnt4D(self, ut):
        "Evaluate parametric point[s] and return 4D homogeneous coordinates"
        ut = numerix.asarray(ut, numerix.Float)
        if numerix.any(ut < 0.) or numerix.any(ut > 1.):
            raise NURBSError, 'NURBS curve parameter out of range [0,1]'
        return bspeval(self.degree, self.cntrl, self.uknots, ut)

    def plot(self, n=50):
        """A simple plotting function for debugging purpose
	n = number of subdivisions.
	Depends on the matplotlib library."""
        try:
            import pylab as P
        except ImportError, value:
            print 'Pylab (matplotlib) plotting library not available'
            return

        pnts = self.pnt3D(numerix.linspace(0., 1, n))
        knots = self.pnt3D(self.uknots)

        maxminx = numerix.sort(self.cntrl[0, :] / self.cntrl[3, :])
        minx = maxminx[0]
        maxx = maxminx[-1]
        if minx == maxx:
            minx -= 1.
            maxx += 1.
        maxminy = numerix.sort(self.cntrl[1, :] / self.cntrl[3, :])
        miny = maxminy[0]
        maxy = maxminy[-1]
        if miny == maxy:
            miny -= 1.
            maxy += 1.
        maxminz = numerix.sort(self.cntrl[2, :] / self.cntrl[3, :])
        minz = maxminz[0]
        maxz = maxminz[-1]
        if minz == maxz:
            minz -= 1.
            maxz += 1.

        P.figure()
        P.plot(pnts[0, :], pnts[1, :])
        P.plot(self.cntrl[0, :] / self.cntrl[3, :],
               self.cntrl[1, :] / self.cntrl[3, :], 'r:o')
        P.plot(knots[0, :], knots[1, :], 'go')
        P.xlabel("X-axis")
        P.ylabel("Y-axis")
        P.axis("scaled")
        P.show()
        P.close()
Exemplo n.º 25
0
class Srf:
    '''Construct a NURB surface structure, and check the format.
    
 The NURB surface is represented by a 4 dimensional b-spline.

 INPUT:

    cntrl  - Control points, homogeneous coordinates (wx,wy,wz,w)
        For a surface [dim,nu,nv] matrix
            where nu  is along the u direction and
            nv  is along the v direction.
            dim is the dimension valid options are:
            2 .... (x,y)        2D cartesian coordinates
            3 .... (x,y,z)      3D cartesian coordinates   
            4 .... (wx,wy,wz,w) 4D homogeneous coordinates

    uknots - Knot sequence along the parametric u direction.
    vknots - Knot sequence along the paramteric v direction.

 NOTES:

    Its assumed that the input knot sequences span the
    interval [0.0,1.0] and are clamped to the control
    points at the end by a knot multiplicity equal to
    the spline order.'''
    def __init__(self, cntrl, uknots, vknots):
        self._bezier = None
        cntrl = numerix.asarray(cntrl, numerix.Float)
        (dim, nu, nv) = cntrl.shape
        if dim < 2 or dim > 4:
            raise NURBSError, 'Illegal control point format'
        elif dim < 4:
            self.cntrl = numerix.zeros((4, nu, nv), numerix.Float)
            self.cntrl[0:dim, :, :] = cntrl
            self.cntrl[-1, :, :] = numerix.ones((nu, nv), numerix.Float)
        else:
            self.cntrl = cntrl

        # Force the u knot sequence to be a vector in ascending order
        # and normalise between [0.0,1.0]
        uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
        nku = uknots.shape[0]
        uknots = (uknots - uknots[0]) / (uknots[-1] - uknots[0])
        if uknots[0] == uknots[-1]:
            raise NURBSError, 'Illegal uknots sequence'
        self.uknots = uknots

        # Force the v knot sequence to be a vector in ascending order
        # and normalise between [0.0,1.0]
        vknots = -numerix.sort(-numerix.asarray(vknots, numerix.Float))
        nkv = vknots.shape[0]
        vknots = (vknots - vknots[0]) / (vknots[-1] - vknots[0])
        if vknots[0] == vknots[-1]:
            raise NURBSError, 'Illegal vknots sequence'
        self.vknots = vknots

        # Spline Degree
        self.degree = [nku - nu - 1, nkv - nv - 1]
        if self.degree[0] < 0 or self.degree[1] < 0:
            raise NURBSError, 'NURBS order must be a positive integer'

    def trans(self, mat):
        "Apply the 4D transform matrix to the NURB control points."
        for v in range(self.cntrl.shape[2]):
            self.cntrl[:, :, v] = numerix.dot(mat, self.cntrl[:, :, v])

    def swapuv(self):
        "Swap u and v parameters."
        self.cntrl = numerix.transpose(self.cntrl, (0, 2, 1))
        temp = self.uknots[:]
        self.uknots = self.vknots[:]
        self.vknots = temp
        udegree, vdegree = self.degree
        self.degree[0] = vdegree
        self.degree[1] = udegree

    def reverse(self):
        "Reverse evaluation directions."
        coefs = self.cntrl[:, :, ::-1]
        self.cntrl = coefs[:, ::-1, :]
        self.uknots = 1. - self.uknots[::-1]
        self.vknots = 1. - self.vknots[::-1]

    def extractV(self, u):
        "Extract curve in v-direction at parameter u."
        if numerix.any(u < 0.) or numerix.any(u > 1.):
            raise NURBSError, 'Out of parameter range [0,1]'
        if u == 0.:
            cntrl = self.cntrl[:, 0, :]
            knots = self.vknots[:]
        elif u == 1.:
            cntrl = self.cntrl[:, -1, :]
            knots = self.vknots[:]
        else:
            uknots = numerix.repeat(
                numerix.asarray([u], numerix.Float),
                [self.degree[1] * (self.cntrl.shape[2] + 1)])
            coefs = numerix.transpose(self.cntrl, (0, 2, 1))
            coefs = numerix.resize(
                coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1]))
            coefs, knots = bspkntins(self.degree[0], coefs, self.uknots,
                                     uknots)
            coefs = numerix.resize(coefs,
                                   (4, self.cntrl.shape[2], coefs.shape[1]))
            cntrl = numerix.transpose(coefs, (0, 2, 1))
            i = 0
            j = knots[0]
            for k in knots[1:]:
                if k == u:
                    break
                elif k != j:
                    i += 1
                    j = k
        return Crv.Crv(cntrl[:, i, :], self.vknots[:])

    def extractU(self, v):
        "Extract curve in u-direction at parameter v."
        if numerix.any(v < 0.) or numerix.any(v > 1.):
            raise NURBSError, 'Out of parameter range [0,1]'
        if v == 0.:
            cntrl = self.cntrl[:, :, 0]
            knots = self.uknots[:]
        elif v == 1.:
            cntrl = self.cntrl[:, :, -1]
            knots = self.uknots[:]
        else:
            vknots = numerix.repeat(
                numerix.asarray([v], numerix.Float),
                [self.degree[0] * (self.cntrl.shape[1] + 1)])
            coefs = numerix.resize(
                self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
            coefs, knots = bspkntins(self.degree[1], coefs, self.vknots,
                                     vknots)
            cntrl = numerix.resize(coefs,
                                   (4, self.cntrl.shape[1], coefs.shape[1]))
            i = 0
            j = knots[0]
            for k in knots[1:]:
                if k == v:
                    break
                elif k != j:
                    i += 1
                    j = k
        return Crv.Crv(cntrl[:, :, i], self.uknots[:])

    def kntins(self, uknots, vknots=None):
        """Insert new knots into the surface
	uknots - knots to be inserted along u direction
	vknots - knots to be inserted along v direction
	NOTE: No knot multiplicity will be increased beyond the order of the spline"""
        if len(vknots):
            # Force the v knot sequence to be a vector in ascending order
            vknots = numerix.sort(numerix.asarray(vknots, numerix.Float))
            if numerix.any(vknots < 0.) or numerix.any(vknots > 1.):
                raise NURBSError, 'Illegal vknots sequence'
            coefs = numerix.resize(
                self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
            coefs, self.vknots = bspkntins(self.degree[1], coefs, self.vknots,
                                           vknots)
            self.cntrl = numerix.resize(
                coefs, (4, self.cntrl.shape[1], coefs.shape[1]))
        if len(uknots):
            # Force the u knot sequence to be a vector in ascending order
            uknots = numerix.sort(numerix.asarray(uknots, numerix.Float))
            if numerix.any(uknots < 0.) or numerix.any(uknots > 1.):
                raise NURBSError, 'Illegal uknots sequence'
            coefs = numerix.transpose(self.cntrl, (0, 2, 1))
            coefs = numerix.resize(
                coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1]))
            coefs, self.uknots = bspkntins(self.degree[0], coefs, self.uknots,
                                           uknots)
            coefs = numerix.resize(coefs,
                                   (4, self.cntrl.shape[2], coefs.shape[1]))
            self.cntrl = numerix.transpose(coefs, (0, 2, 1))

    def degelev(self, utimes, vtimes=None):
        """Degree elevate the surface.
	utimes - degree elevate utimes along u direction.
	vtimes - degree elevate vtimes along v direction."""
        if vtimes:
            if vtimes < 0:
                raise NURBSError, 'Degree must be positive'
            coefs = numerix.resize(
                self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
            coefs, vknots, nh = bspdegelev(self.degree[1], coefs, self.vknots,
                                           vtimes)
            coefs = coefs[:, :nh + 1]
            self.vknots = vknots[:nh + self.degree[1] + vtimes + 2]
            self.degree[1] += vtimes
            self.cntrl = numerix.resize(
                coefs, (4, self.cntrl.shape[1], coefs.shape[1]))
        if utimes:
            if utimes < 0:
                raise NURBSError, 'Degree must be positive'
            coefs = numerix.transpose(self.cntrl, (0, 2, 1))
            coefs = numerix.resize(
                coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1]))
            coefs, uknots, nh = bspdegelev(self.degree[0], coefs, self.uknots,
                                           utimes)
            coefs = coefs[:, :nh + 1]
            self.uknots = uknots[:nh + self.degree[0] + utimes + 2]
            self.degree[0] += utimes
            coefs = numerix.resize(coefs,
                                   (4, self.cntrl.shape[2], coefs.shape[1]))
            self.cntrl = numerix.transpose(coefs, (0, 2, 1))

    def bezier(self, update=None):
        "Decompose surface to bezier patches and return overlaping control points."
        if update or not self._bezier:
            cntrl = numerix.resize(
                self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
            cntrl = bspbezdecom(self.degree[1], cntrl, self.vknots)
            cntrl = numerix.resize(cntrl,
                                   (4, self.cntrl.shape[1], cntrl.shape[1]))
            temp1 = cntrl.shape[1]
            temp2 = cntrl.shape[2]
            cntrl = numerix.transpose(cntrl, (0, 2, 1))
            cntrl = numerix.resize(cntrl, (4 * temp2, temp1))
            cntrl = bspbezdecom(self.degree[0], cntrl, self.uknots)
            cntrl = numerix.resize(cntrl, (4, temp2, cntrl.shape[1]))
            self._bezier = numerix.transpose(cntrl, (0, 2, 1))
        return self._bezier

    def bounds(self):
        "Return the bounding box for the surface."
        w = self.cntrl[3, :, :]
        cx = numerix.sort(numerix.ravel(self.cntrl[0, :, :] / w))
        cy = numerix.sort(numerix.ravel(self.cntrl[1, :, :] / w))
        cz = numerix.sort(numerix.ravel(self.cntrl[2, :, :] / w))
        return numerix.asarray([cx[0], cy[0], cz[0], cx[-1], cy[-1], cz[-1]],
                               numerix.Float)

    def pnt3D(self, ut, vt=None):
        """Evaluate parametric point[s] and return 3D cartesian coordinate[s]
	If only ut is given then we will evaluate at scattered points.
	ut(0,:) represents the u direction.
	ut(1,:) represents the v direction.
	If both parameters are given then we will evaluate over a [u,v] grid."""
        val = self.pnt4D(ut, vt)
        if len(val.shape) < 3:
            return val[0:3, :] / numerix.resize(val[-1, :], (3, val.shape[1]))
        else:  #FIX!
            return val[0:3, :, :] / numerix.resize(
                val[-1, :, :], (3, val.shape[1], val.shape[2]))

    def pnt4D(self, ut, vt=None):
        """Evaluate parametric point[s] and return 4D homogeneous coordinates.
	If only ut is given then we will evaluate at scattered points.
	ut(0,:) represents the u direction.
	ut(1,:) represents the v direction.
	If both parameters are given then we will evaluate over a [u,v] grid."""
        ut = numerix.asarray(ut, numerix.Float)
        if numerix.any(ut < 0.) or numerix.any(ut > 1.):
            raise NURBSError, 'NURBS curve parameter out of range [0,1]'

        if vt:  #FIX!
            # Evaluate over a [u,v] grid
            vt = numerix.asarray(vt, numerix.Float)
            if numerix.any(vt < 0.) or numerix.any(vt > 1.):
                raise NURBSError, 'NURBS curve parameter out of range [0,1]'

            val = numerix.resize(
                self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
            val = bspeval(self.degree[1], val, self.vknots, vt)
            val = numerix.resize(val, (4, self.cntrl.shape[1], vt.shape[0]))

            val = numerix.transpose(val, (0, 2, 1))

            val = numerix.resize(self.cntrl,
                                 (4 * vt.shape[0], self.cntrl.shape[1]))
            val = bspeval(self.degree[0], val, self.uknots, ut)
            val = numerix.resize(val, (4, vt.shape[0], ut.shape[0]))

            return numerix.transpose(val, (0, 2, 1))

        # Evaluate at scattered points
        nt = ut.shape[1]
        uval = numerix.resize(self.cntrl,
                              (4 * self.cntrl.shape[1], self.cntrl.shape[2]))
        uval = bspeval(self.degree[1], uval, self.vknots, ut[1, :])
        uval = numerix.resize(uval, (4, self.cntrl.shape[1], nt))

        val = numerix.zeros((4, nt), numerix.Float)
        for v in range(nt):
            val[:, v] = bspeval(
                self.degree[0],
                numerix.resize(uval[:, :, v], (4, self.cntrl.shape[1])),
                self.uknots, (ut[0, v], ))[:, 0]
        return val

    def plot(self, n=50, iso=8):
        """A simple plotting function based on dislin for debugging purpose.
	n = number of subdivisions. iso = number of iso line to plot in each dir.
	TODO: plot ctrl poins and knots."""
        try:
            import dislin
        except ImportError, value:
            print 'dislin plotting library not available'
            return

        maxminx = numerix.sort(
            numerix.ravel(self.cntrl[0, :, :]) /
            numerix.ravel(self.cntrl[3, :, :]))
        minx = maxminx[0]
        maxx = maxminx[-1]
        if minx == maxx:
            minx -= 1.
            maxx += 1.

        maxminy = numerix.sort(
            numerix.ravel(self.cntrl[1, :, :]) /
            numerix.ravel(self.cntrl[3, :, :]))
        miny = maxminy[0]
        maxy = maxminy[-1]
        if miny == maxy:
            miny -= 1.
            maxy += 1.

        maxminz = numerix.sort(
            numerix.ravel(self.cntrl[2, :, :]) /
            numerix.ravel(self.cntrl[3, :, :]))
        minz = maxminz[0]
        maxz = maxminz[-1]
        if minz == maxz:
            minz -= 1.
            maxz += 1.

        dislin.metafl('cons')
        dislin.disini()
        dislin.hwfont()
        dislin.pagera()
        dislin.name('X-axis', 'X')
        dislin.name('Y-axis', 'Y')
        dislin.name('Z-axis', 'Z')
        dislin.graf3d(minx, maxx, 0, abs((maxx - minx) / 4.), miny, maxy, 0,
                      abs((maxy - miny) / 4.), minz, maxz, 0,
                      abs((maxz - minz) / 4.))

        dislin.color('yellow')
        pnts0 = self.pnt3D([
            numerix.arange(n + 1, typecode=numerix.Float) / n,
            numerix.zeros(n + 1, numerix.Float)
        ])
        pnts1 = self.pnt3D([
            numerix.arange(n + 1, typecode=numerix.Float) / n,
            numerix.ones(n + 1, numerix.Float)
        ])
        pnts2 = self.pnt3D([
            numerix.zeros(n + 1, numerix.Float),
            numerix.arange(n + 1, typecode=numerix.Float) / n
        ])
        pnts3 = self.pnt3D([
            numerix.ones(n + 1, numerix.Float),
            numerix.arange(n + 1, typecode=numerix.Float) / n
        ])
        dislin.curv3d(pnts0[0, :], pnts0[1, :], pnts0[2, :], n + 1)
        dislin.curv3d(pnts1[0, :], pnts1[1, :], pnts1[2, :], n + 1)
        dislin.curv3d(pnts2[0, :], pnts2[1, :], pnts2[2, :], n + 1)
        dislin.curv3d(pnts3[0, :], pnts3[1, :], pnts3[2, :], n + 1)

        dislin.color('red')
        step = 1. / iso
        for uv in numerix.arange(step, 1., step):
            pnts = self.pnt3D([
                numerix.arange(n + 1, typecode=numerix.Float) / n,
                numerix.zeros(n + 1, numerix.Float) + uv
            ])
            dislin.curv3d(pnts[0, :], pnts[1, :], pnts[2, :], n + 1)
            pnts = self.pnt3D([
                numerix.zeros(n + 1, numerix.Float) + uv,
                numerix.arange(n + 1, typecode=numerix.Float) / n
            ])
            dislin.curv3d(pnts[0, :], pnts[1, :], pnts[2, :], n + 1)

        dislin.disfin()