Ejemplo n.º 1
0
/*******************************************************************************
 ** Make points array for visible atoms
 *******************************************************************************/
static PyObject*
makeVisiblePointsArray(PyObject *self, PyObject *args)
{
    int NVisible;
    PyArrayObject *visibleAtoms=NULL;
    PyArrayObject *pos=NULL;

    int i;
    npy_intp numpydims[2];
    PyArrayObject *visiblePos=NULL;

    /* parse and check arguments from Python */
    if (!PyArg_ParseTuple(args, "O!O!", &PyArray_Type, &visibleAtoms, &PyArray_Type, &pos))
        return NULL;

    if (not_intVector(visibleAtoms)) return NULL;
    NVisible = (int) PyArray_DIM(visibleAtoms, 0);

    if (not_doubleVector(pos)) return NULL;

    /* create radius array */
    numpydims[0] = (npy_intp) NVisible;
    numpydims[1] = 3;
    visiblePos = (PyArrayObject *) PyArray_SimpleNew(2, numpydims, NPY_FLOAT64);

    /* populate array */
    for (i = 0; i < NVisible; i++)
    {
        int index, index3, j;

        index = IIND1(visibleAtoms, i);
        index3 = index * 3;

        for (j = 0; j < 3; j++)
            DIND2(visiblePos, i, j) = DIND1(pos, index3 + j);
    }

    return PyArray_Return(visiblePos);
}
Ejemplo n.º 2
0
/*******************************************************************************
 ** Make arrays for rendering bonds for displacment vectors
 *******************************************************************************/
static PyObject*
makeDisplacementVectorBondsArrays(PyObject *self, PyObject *args)
{
    int numBonds;
    PyArrayObject *visibleAtoms=NULL;
    PyArrayObject *scalarsArray=NULL;
    PyArrayObject *pos=NULL;
    PyArrayObject *drawBondArray=NULL;
    PyArrayObject *bondVectorsArray=NULL;
    PyObject *result=NULL;

    /* parse arguments from Python */
    if (PyArg_ParseTuple(args, "iO!O!O!O!O!", &numBonds, &PyArray_Type, &visibleAtoms, &PyArray_Type, &scalarsArray,
                         &PyArray_Type, &pos, &PyArray_Type, &drawBondArray, &PyArray_Type, &bondVectorsArray))
    {
        int i, count, numVisible;
        npy_intp numpydims[2];
        PyArrayObject *bondCoords = NULL;
        PyArrayObject *bondScalars = NULL;
        PyArrayObject *bondVectors = NULL;

        /* check arguments */
        if (not_intVector(visibleAtoms)) return NULL;
        numVisible = (int) PyArray_DIM(visibleAtoms, 0);
        if (not_doubleVector(scalarsArray)) return NULL;
        if (not_doubleVector(pos)) return NULL;
        if (not_intVector(drawBondArray)) return NULL;
        if (not_doubleVector(bondVectorsArray)) return NULL;

        /* create array for bond coordinates */
        numpydims[0] = (npy_intp) numBonds;
        numpydims[1] = 3;
        bondCoords = (PyArrayObject *) PyArray_SimpleNew(2, numpydims, NPY_FLOAT64);
        if (bondCoords == NULL)
        {
            PyErr_SetString(PyExc_MemoryError, "Could not allocate bondCoords");
            return NULL;
        }

        /* create array for bond vectors */
        numpydims[0] = (npy_intp) numBonds;
        numpydims[1] = 3;
        bondVectors = (PyArrayObject *) PyArray_SimpleNew(2, numpydims, NPY_FLOAT64);
        if (bondVectors == NULL)
        {
            PyErr_SetString(PyExc_MemoryError, "Could not allocate bondVectors");
            Py_DECREF(bondCoords);
            return NULL;
        }

        /* create array for bond scalars */
        numpydims[0] = (npy_intp) numBonds;
        bondScalars = (PyArrayObject *) PyArray_SimpleNew(1, numpydims, NPY_FLOAT64);
        if (bondScalars == NULL)
        {
            PyErr_SetString(PyExc_MemoryError, "Could not allocate bondScalars");
            Py_DECREF(bondCoords);
            Py_DECREF(bondVectors);
            return NULL;
        }

        /* loop over visible atoms */
        count = 0;
        for (i = 0; i < numVisible; i++)
        {
            /* check if we should be drawing this bond */
            if (IIND1(drawBondArray, i))
            {
                int j, i3 = 3 * i;
                int index3 = 3 * IIND1(visibleAtoms, i);

                /* store bond values */
                for (j = 0; j < 3; j++)
                {
                    DIND2(bondCoords, count, j) = DIND1(pos, index3 + j);
                    DIND2(bondVectors, count, j) = DIND1(bondVectorsArray, i3 + j);
                }
                DIND1(bondScalars, count) = DIND1(scalarsArray, i);
                count++;
            }
        }

        /* tuple for result */
        result = PyTuple_New(3);
        PyTuple_SetItem(result, 0, PyArray_Return(bondCoords));
        PyTuple_SetItem(result, 1, PyArray_Return(bondVectors));
        PyTuple_SetItem(result, 2, PyArray_Return(bondScalars));
    }

    return result;
}
Ejemplo n.º 3
0
/*******************************************************************************
 ** Split visible atoms by specie (position and scalar)
 *******************************************************************************/
static PyObject*
splitVisAtomsBySpecie(PyObject *self, PyObject *args)
{
    int NVisible, *visibleAtoms, NSpecies, *specieArray, *specieCount, scalarType, heightAxis, vectorsLen;
    double *pos, *PE, *KE, *charge, *scalars;
    PyArrayObject *visibleAtomsIn=NULL;
    PyArrayObject *specieArrayIn=NULL;
    PyArrayObject *specieCountIn=NULL;
    PyArrayObject *posIn=NULL;
    PyArrayObject *PEIn=NULL;
    PyArrayObject *KEIn=NULL;
    PyArrayObject *chargeIn=NULL;
    PyArrayObject *scalarsIn=NULL;
    PyArrayObject *vectors=NULL;

    int i, j, index, specie, count;
    npy_intp numpyDims[2];
    double scalar;
    PyObject *list=NULL;


    /* parse and check arguments from Python */
    if (!PyArg_ParseTuple(args, "O!iO!O!O!O!O!O!O!iiO!", &PyArray_Type, &visibleAtomsIn, &NSpecies, &PyArray_Type, &specieArrayIn,
                          &PyArray_Type, &specieCountIn, &PyArray_Type, &posIn, &PyArray_Type, &PEIn, &PyArray_Type, &KEIn, &PyArray_Type,
                          &chargeIn, &PyArray_Type, &scalarsIn, &scalarType, &heightAxis, &PyArray_Type, &vectors))
        return NULL;

    if (not_intVector(visibleAtomsIn)) return NULL;
    visibleAtoms = pyvector_to_Cptr_int(visibleAtomsIn);
    NVisible = (int) PyArray_DIM(visibleAtomsIn, 0);

    if (not_intVector(specieArrayIn)) return NULL;
    specieArray = pyvector_to_Cptr_int(specieArrayIn);

    if (not_intVector(specieCountIn)) return NULL;
    specieCount = pyvector_to_Cptr_int(specieCountIn);

    if (not_doubleVector(posIn)) return NULL;
    pos = pyvector_to_Cptr_double(posIn);

    if (not_doubleVector(PEIn)) return NULL;
    PE = pyvector_to_Cptr_double(PEIn);

    if (not_doubleVector(KEIn)) return NULL;
    KE = pyvector_to_Cptr_double(KEIn);

    if (not_doubleVector(chargeIn)) return NULL;
    charge = pyvector_to_Cptr_double(chargeIn);

    if (not_doubleVector(scalarsIn)) return NULL;
    scalars = pyvector_to_Cptr_double(scalarsIn);

    if (not_doubleVector(vectors)) return NULL;
    vectorsLen = (int) PyArray_DIM(vectors, 0);

    /* first pass to get counters, assume counter zeroed before */
    for (i = 0; i < NVisible; i++)
    {
        index = visibleAtoms[i];
        specie = specieArray[index];
        specieCount[specie]++;
    }

    /* create list for returning */
    list = PyList_New(NSpecies);

    /* loop over species */
    for (i = 0; i < NSpecies; i++)
    {
        PyArrayObject *speciePos = NULL;
        PyArrayObject *specieScalars = NULL;
        PyArrayObject *specieVectors = NULL;
        PyObject *tuple = NULL;

        /* allocate position array */
        numpyDims[0] = (npy_intp) specieCount[i];
        numpyDims[1] = 3;
        speciePos = (PyArrayObject *) PyArray_SimpleNew(2, numpyDims, NPY_FLOAT64);

        /* allocate position array */
        numpyDims[0] = (npy_intp) specieCount[i];
        specieScalars = (PyArrayObject *) PyArray_SimpleNew(1, numpyDims, NPY_FLOAT64);

        if (vectorsLen > 0)
        {
            /* allocate vectors array */
            numpyDims[0] = (npy_intp) specieCount[i];
            numpyDims[1] = 3;
            specieVectors = (PyArrayObject *) PyArray_SimpleNew(2, numpyDims, NPY_FLOAT64);
        }
        else
        {
            numpyDims[0] = 0;
            specieVectors = (PyArrayObject *) PyArray_SimpleNew(1, numpyDims, NPY_FLOAT64);
        }

        /* loop over atoms */
        count = 0;
        for (j = 0; j < NVisible; j++)
        {
            index = visibleAtoms[j];
            specie = specieArray[index];

            if (specie == i)
            {
                /* position */
                DIND2(speciePos, count, 0) = pos[3*index+0];
                DIND2(speciePos, count, 1) = pos[3*index+1];
                DIND2(speciePos, count, 2) = pos[3*index+2];

                /* scalar */
                if (scalarType == 0) scalar = specie;
                else if (scalarType == 1) scalar = pos[3*index+heightAxis];
                else if (scalarType == 2) scalar = KE[index];
                else if (scalarType == 3) scalar = PE[index];
                else if (scalarType == 4) scalar = charge[index];
                else scalar = scalars[j];

                DIND1(specieScalars, count) = scalar;

                if (vectorsLen > 0)
                {
                    /* vector */
                    DIND2(specieVectors, count, 0) = DIND2(vectors, index, 0);
                    DIND2(specieVectors, count, 1) = DIND2(vectors, index, 1);
                    DIND2(specieVectors, count, 2) = DIND2(vectors, index, 2);
                }

                count++;
            }
        }

        /* create tuple (setItem steals ownership of array objects!!??) */
        tuple = PyTuple_New(3);
        PyTuple_SetItem(tuple, 0, PyArray_Return(speciePos));
        PyTuple_SetItem(tuple, 1, PyArray_Return(specieScalars));
        PyTuple_SetItem(tuple, 2, PyArray_Return(specieVectors));

        /* store in list (setItem steals ownership of tuple!?) */
        PyList_SetItem(list, i, tuple);
    }

    return list;
}
Ejemplo n.º 4
0
/*******************************************************************************
 ** Make arrays for rendering bonds
 *******************************************************************************/
static PyObject*
makeBondsArrays(PyObject *self, PyObject *args)
{
    PyArrayObject *visibleAtoms=NULL;
    PyArrayObject *scalarsArray=NULL;
    PyArrayObject *pos=NULL;
    PyArrayObject *numBondsArray=NULL;
    PyArrayObject *bondsArray=NULL;
    PyArrayObject *bondVectorsArray=NULL;
    PyObject *result=NULL;

    /* parse arguments from Python */
    if (PyArg_ParseTuple(args, "O!O!O!O!O!O!", &PyArray_Type, &visibleAtoms, &PyArray_Type, &scalarsArray,
                         &PyArray_Type, &pos, &PyArray_Type, &numBondsArray, &PyArray_Type, &bondsArray, &PyArray_Type,
                         &bondVectorsArray))
    {
        int i, numVisible, numBonds, count, bondCount;
        npy_intp numpydims[2];
        PyArrayObject *bondCoords = NULL;
        PyArrayObject *bondScalars = NULL;
        PyArrayObject *bondVectors = NULL;

        /* check arguments */
        if (not_intVector(visibleAtoms)) return NULL;
        numVisible = (int) PyArray_DIM(visibleAtoms, 0);
        if (not_doubleVector(scalarsArray)) return NULL;
        if (not_doubleVector(pos)) return NULL;
        if (not_intVector(numBondsArray)) return NULL;
        if (not_intVector(bondsArray)) return NULL;
        if (not_doubleVector(bondVectorsArray)) return NULL;

        /* calculate the number of bonds */
        numBonds = 0;
        for (i = 0; i < numVisible; i++) numBonds += IIND1(numBondsArray, i);
        /* multiply by two as there are two "bonds" drawn per real bond */
        numBonds *= 2;

        /* create array for bond coordinates */
        numpydims[0] = (npy_intp) numBonds;
        numpydims[1] = 3;
        bondCoords = (PyArrayObject *) PyArray_SimpleNew(2, numpydims, NPY_FLOAT64);
        if (bondCoords == NULL)
        {
            PyErr_SetString(PyExc_MemoryError, "Could not allocate bondCoords");
            return NULL;
        }

        /* create array for bond vectors */
        numpydims[0] = (npy_intp) numBonds;
        numpydims[1] = 3;
        bondVectors = (PyArrayObject *) PyArray_SimpleNew(2, numpydims, NPY_FLOAT64);
        if (bondVectors == NULL)
        {
            PyErr_SetString(PyExc_MemoryError, "Could not allocate bondVectors");
            Py_DECREF(bondCoords);
            return NULL;
        }

        /* create array for bond scalars */
        numpydims[0] = (npy_intp) numBonds;
        bondScalars = (PyArrayObject *) PyArray_SimpleNew(1, numpydims, NPY_FLOAT64);
        if (bondScalars == NULL)
        {
            PyErr_SetString(PyExc_MemoryError, "Could not allocate bondScalars");
            Py_DECREF(bondCoords);
            Py_DECREF(bondVectors);
            return NULL;
        }

        /* loop over visible atoms */
        count = 0;
        bondCount = 0;
        for (i = 0; i < numVisible; i++)
        {
            int j;
            int indexa = IIND1(visibleAtoms, i);
            int indexa3 = 3 * indexa;
            int numBondsForAtom = IIND1(numBondsArray, i);
            double xposa, yposa, zposa, scalara;

            /* atom position and scalar */
            xposa = DIND1(pos, indexa3    );
            yposa = DIND1(pos, indexa3 + 1);
            zposa = DIND1(pos, indexa3 + 2);
            scalara = DIND1(scalarsArray, i);

            /* loop over this atoms bonds */
            for (j = 0; j < numBondsForAtom; j++)
            {
                int cnt3 = count * 3;
                int visIndex = IIND1(bondsArray, count);
                int indexb3 = 3 * IIND1(visibleAtoms, visIndex);
                double xposb = DIND1(pos, indexb3    );
                double yposb = DIND1(pos, indexb3 + 1);
                double zposb = DIND1(pos, indexb3 + 2);
                double scalarb = DIND1(scalarsArray, visIndex);
                double bvecx = DIND1(bondVectorsArray, cnt3    );
                double bvecy = DIND1(bondVectorsArray, cnt3 + 1);
                double bvecz = DIND1(bondVectorsArray, cnt3 + 2);

                /* partial bond from atom a towards b */
                DIND2(bondCoords, bondCount, 0) = xposa;
                DIND2(bondCoords, bondCount, 1) = yposa;
                DIND2(bondCoords, bondCount, 2) = zposa;
                DIND2(bondVectors, bondCount, 0) = bvecx;
                DIND2(bondVectors, bondCount, 1) = bvecy;
                DIND2(bondVectors, bondCount, 2) = bvecz;
                DIND1(bondScalars, bondCount) = scalara;
                bondCount++;

                /* partial bond from atom b towards a */
                DIND2(bondCoords, bondCount, 0) = xposb;
                DIND2(bondCoords, bondCount, 1) = yposb;
                DIND2(bondCoords, bondCount, 2) = zposb;
                DIND2(bondVectors, bondCount, 0) = -1.0 * bvecx;
                DIND2(bondVectors, bondCount, 1) = -1.0 * bvecy;
                DIND2(bondVectors, bondCount, 2) = -1.0 * bvecz;
                DIND1(bondScalars, bondCount) = scalarb;
                bondCount++;

                count++;
            }
        }

        /* tuple for result */
        result = PyTuple_New(3);
        PyTuple_SetItem(result, 0, PyArray_Return(bondCoords));
        PyTuple_SetItem(result, 1, PyArray_Return(bondVectors));
        PyTuple_SetItem(result, 2, PyArray_Return(bondScalars));
    }

    return result;
}
Ejemplo n.º 5
0
/*******************************************************************************
 ** Calculate the bond order parameters and filter atoms (if required).
 **
 ** Inputs:
 **     - visibleAtoms: the list of atoms that are currently visible
 **     - pos: positions of all the atoms
 **     - maxBondDistance: the maximum bond distance to consider
 **     - scalarsQ4: array to store the Q4 parameter value
 **     - scalarsQ6: array to store the Q6 parameter value
 **     - cellDims: simulation cell dimensions
 **     - PBC: periodic boundaries conditions
 **     - NScalars: the number of previously calculated scalar values
 **     - fullScalars: the full list of previously calculated scalars
 **     - NVectors: the number of previously calculated vector values
 **     - fullVectors: the full list of previously calculated vectors
 **     - filterQ4: filter atoms by the Q4 parameter
 **     - minQ4: the minimum Q4 for an atom to be visible
 **     - maxQ4: the maximum Q4 for an atom to be visible
 **     - filterQ6: filter atoms by the Q6 parameter
 **     - minQ6: the minimum Q6 for an atom to be visible
 **     - maxQ6: the maximum Q6 for an atom to be visible
 *******************************************************************************/
static PyObject*
bondOrderFilter(PyObject *self, PyObject *args)
{
    int NVisibleIn, *visibleAtoms, *PBC, NScalars, filterQ4Enabled, filterQ6Enabled;
    int NVectors;
    double maxBondDistance, *scalarsQ4, *scalarsQ6, *cellDims;
    double *pos, *fullScalars, minQ4, maxQ4, minQ6, maxQ6;
    PyArrayObject *posIn=NULL;
    PyArrayObject *visibleAtomsIn=NULL;
    PyArrayObject *PBCIn=NULL;
    PyArrayObject *scalarsQ4In=NULL;
    PyArrayObject *scalarsQ6In=NULL;
    PyArrayObject *cellDimsIn=NULL;
    PyArrayObject *fullScalarsIn=NULL;
    PyArrayObject *fullVectors=NULL;

    int i, NVisible, boxstat;
    double *visiblePos, maxSep2;
    struct Boxes *boxes;
    struct NeighbourList *nebList;
    struct AtomStructureResults *results;

    /* parse and check arguments from Python */
    if (!PyArg_ParseTuple(args, "O!O!dO!O!O!O!iO!iddiddiO!", &PyArray_Type, &visibleAtomsIn, &PyArray_Type, &posIn, &maxBondDistance,
            &PyArray_Type, &scalarsQ4In, &PyArray_Type, &scalarsQ6In, &PyArray_Type, &cellDimsIn, &PyArray_Type, &PBCIn, &NScalars,
            &PyArray_Type, &fullScalarsIn, &filterQ4Enabled, &minQ4, &maxQ4, &filterQ6Enabled, &minQ6, &maxQ6, &NVectors,
            &PyArray_Type, &fullVectors))
        return NULL;

    if (not_intVector(visibleAtomsIn)) return NULL;
    visibleAtoms = pyvector_to_Cptr_int(visibleAtomsIn);
    NVisibleIn = (int) PyArray_DIM(visibleAtomsIn, 0);

    if (not_doubleVector(posIn)) return NULL;
    pos = pyvector_to_Cptr_double(posIn);

    if (not_doubleVector(scalarsQ4In)) return NULL;
    scalarsQ4 = pyvector_to_Cptr_double(scalarsQ4In);

    if (not_doubleVector(scalarsQ6In)) return NULL;
    scalarsQ6 = pyvector_to_Cptr_double(scalarsQ6In);

    if (not_doubleVector(cellDimsIn)) return NULL;
    cellDims = pyvector_to_Cptr_double(cellDimsIn);

    if (not_intVector(PBCIn)) return NULL;
    PBC = pyvector_to_Cptr_int(PBCIn);

    if (not_doubleVector(fullScalarsIn)) return NULL;
    fullScalars = pyvector_to_Cptr_double(fullScalarsIn);

    if (not_doubleVector(fullVectors)) return NULL;

    /* construct array of positions of visible atoms */
    visiblePos = malloc(3 * NVisibleIn * sizeof(double));
    if (visiblePos == NULL)
    {
        PyErr_SetString(PyExc_MemoryError, "Could not allocate visiblePos");
        return NULL;
    }
    for (i = 0; i < NVisibleIn; i++)
    {
        int index = visibleAtoms[i];
        int ind3 = 3 * index;
        int i3 = 3 * i;
        visiblePos[i3    ] = pos[ind3    ];
        visiblePos[i3 + 1] = pos[ind3 + 1];
        visiblePos[i3 + 2] = pos[ind3 + 2];
    }

    /* box visible atoms */
    boxes = setupBoxes(maxBondDistance, PBC, cellDims);
    if (boxes == NULL)
    {
        free(visiblePos);
        return NULL;
    }
    boxstat = putAtomsInBoxes(NVisibleIn, visiblePos, boxes);
    if (boxstat)
    {
        free(visiblePos);
        return NULL;
    }

    /* build neighbour list */
    maxSep2 = maxBondDistance * maxBondDistance;
    nebList = constructNeighbourList(NVisibleIn, visiblePos, boxes, cellDims, PBC, maxSep2);

    /* only required for building neb list */
    free(visiblePos);
    freeBoxes(boxes);

    /* return if failed to build the neighbour list */
    if (nebList == NULL) return NULL;

    /* allocate results structure */
    results = malloc(NVisibleIn * sizeof(struct AtomStructureResults));
    if (results == NULL)
    {
        PyErr_SetString(PyExc_MemoryError, "Could not allocate results");
        freeNeighbourList(nebList, NVisibleIn);
        return NULL;
    }

    /* first calc q_lm for each atom over all m values */
    complex_qlm(NVisibleIn, visibleAtoms, nebList, pos, cellDims, PBC, results);

    /* free neighbour list */
    freeNeighbourList(nebList, NVisibleIn);

    /* calculate Q4 and Q6 */
    calculate_Q(NVisibleIn, results);

    /* do filtering here, storing results along the way */
    NVisible = 0;
    for (i = 0; i < NVisibleIn; i++)
    {
        int j;
        double q4 = results[i].Q4;
        double q6 = results[i].Q6;

        /* skip if not within the valid range */
        if (filterQ4Enabled && (q4 < minQ4 || q4 > maxQ4))
            continue;
        if (filterQ6Enabled && (q6 < minQ6 || q6 > maxQ6))
            continue;

        /* store in visible atoms array */
        visibleAtoms[NVisible] = visibleAtoms[i];

        /* store calculated values */
        scalarsQ4[NVisible] = q4;
        scalarsQ6[NVisible] = q6;

        /* update full scalars/vectors arrays */
        for (j = 0; j < NScalars; j++)
        {
            int nj = j * NVisibleIn;
            fullScalars[nj + NVisible] = fullScalars[nj + i];
        }

        for (j = 0; j < NVectors; j++)
        {
            int nj = j * NVisibleIn;
            DIND2(fullVectors, nj + NVisible, 0) = DIND2(fullVectors, nj + i, 0);
            DIND2(fullVectors, nj + NVisible, 1) = DIND2(fullVectors, nj + i, 1);
            DIND2(fullVectors, nj + NVisible, 2) = DIND2(fullVectors, nj + i, 2);
        }

        NVisible++;
    }

    /* free results memory */
    free(results);

    return Py_BuildValue("i", NVisible);
}
Ejemplo n.º 6
0
/*perform 1d fht for each line (first axis) of the input array */
static PyObject *fht2_%(ctype)s(PyObject *self, PyObject *args) {
  PyArrayObject *arr1, *oarr;
  int dim1, dim2;
  unsigned bit, i, j, k;
  CTYPE temp;
  if (!PyArg_ParseTuple(args, "O!O!", &PyArray_Type, &arr1,
			&PyArray_Type, &oarr)) return NULL;
  dim1 = arr1->dimensions[0];
  dim2 = arr1->dimensions[1];
  /* First loop on the first axis (time) */
  #pragma omp parallel shared(arr1, oarr, dim1, dim2) private(i, j, k, bit, temp)
  #pragma omp for
  for (i = 0; i < dim1; i++) {
    /* Hadamard transform on the other axis*/
    for (j = 0; j < dim2; j+=2) {
      k = j+1;
      DIND2(oarr, i, j) = DIND2(arr1, i, j) + DIND2(arr1, i, k);
      DIND2(oarr, i, k) = DIND2(arr1, i, j) - DIND2(arr1, i, k);
    }
    for (bit = 2; bit < dim2; bit <<= 1) {   
      for (j = 0; j < dim2; j++) {
	if( (bit & j) == 0 ) {
	  k = j | bit;
	  temp = DIND2(oarr, i, j);
	  DIND2(oarr, i, j) = DIND2(oarr, i, j) + DIND2(oarr, i, k);
	  DIND2(oarr, i, k) = temp - DIND2(oarr, i, k);
	}
      }
    }
  }
  return Py_BuildValue("d", 1.);
}