Exemple #1
0
/* methods */
static PyObject*
libtfr_tfr_spec(PyObject *self, PyObject *args)
{
        /* arguments */
        PyObject *o = NULL;
        PyArrayObject *signal = NULL;
        PyArrayObject *signal_cast = NULL;
        PyObject *o2 = NULL;
        PyArrayObject *fgrid = NULL;
        PyArrayObject *fgrid_cast = NULL;
        int N;
        int step;
        int Np;
        int K = 6;
        double tm = 6.0;
        double flock = 0.01;
        int tlock = 5;

        /* output data */
        npy_intp out_shape[2];
        PyArrayObject *outdata = NULL;
        double *spec;

        /* internal stuff */
        mfft *mtmh;
        double *samples;
        double *fgridp = NULL;

        /* parse arguments */
        if (!PyArg_ParseTuple(args, "Oiii|iddiO", &o, &N, &step, &Np, &K, &tm, &flock, &tlock, &o2))
                return NULL;
        signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL);
        if (signal==NULL) {
                PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray");
                return NULL;
        }
        int nfreq = N/2+1;

        if (o2!=NULL && o2!=Py_None) {
                fgrid = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 1, NPY_CONTIGUOUS, NULL);
                if (fgrid!=NULL) {
                        fgridp = coerce_ndarray_double(fgrid, &fgrid_cast);
                        if (fgridp==NULL) {
                                PyErr_SetString(PyExc_TypeError, "Unable to cast frequency grid to supported data type");
                                goto fail;
                        }
                        nfreq = PyArray_SIZE(fgrid);
                }
        }

        /* coerce input data to proper type */
        samples = coerce_ndarray_double(signal, &signal_cast);
        if (samples==NULL) {
                PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type");
                goto fail;
        }

	/* initialize transform object - window size may be adjusted */
        mtmh = mtm_init_herm(N, Np, K, tm);

        /* allocate output array  */
        out_shape[0] = nfreq;
        out_shape[1] = SPEC_NFRAMES(mtmh,PyArray_SIZE(signal),step);
        outdata  = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // last arg give fortran-order
        spec = (double*) PyArray_DATA(outdata);


        /* do the transform */
        tfr_spec(mtmh, spec, samples, PyArray_SIZE(signal),
                 -1, step, flock, tlock, nfreq, fgridp);
        mtm_destroy(mtmh);

        Py_DECREF(signal);
        Py_XDECREF(signal_cast);
        Py_XDECREF(fgrid);
        Py_XDECREF(fgrid_cast);
        return PyArray_Return(outdata);
fail:
        Py_XDECREF(fgrid_cast);
        Py_XDECREF(fgrid);
        Py_XDECREF(signal_cast);
        Py_XDECREF(signal);
        return NULL;
}
Exemple #2
0
static PyObject *
potential_energy_and_forces(potential_t *self, PyObject *args, PyObject *kwargs)
{
  static char *kwlist[] = {
    "particles",
    "neighbors",
    "epot_per_at",
    "epot_per_bond",
    "f_per_bond",
    "wpot_per_at",
    "wpot_per_bond",
    NULL
  };

  npy_intp dims[3];
  npy_intp strides[3];

  particles_t *a;
  neighbors_t *n;
  PyObject *return_epot_per_at = NULL;
  PyObject *return_epot_per_bond = NULL;
  PyObject *return_f_per_bond = NULL;
  PyObject *return_wpot_per_at = NULL;
  PyObject *return_wpot_per_bond = NULL;

  int ierror = ERROR_NONE;

  double epot;
  PyObject *f;
  PyObject *wpot;
  PyObject *epot_per_at = NULL;
  PyObject *epot_per_bond = NULL;
  PyObject *f_per_bond = NULL;
  PyObject *wpot_per_at = NULL;
  PyObject *wpot_per_bond = NULL;

  double *epot_per_at_ptr = NULL;
  double *epot_per_bond_ptr = NULL;
  double *f_per_bond_ptr = NULL;
  double *wpot_per_at_ptr = NULL;
  double *wpot_per_bond_ptr = NULL;

  PyObject *r;

  int i;

  /* --- */

#ifdef DEBUG
  printf("[potential_energy_and_forces] self = %p\n", self);
#endif

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!|O!O!O!O!O!", kwlist,
				   &particles_type, &a, &neighbors_type, &n,
				   &PyBool_Type, &return_epot_per_at, 
				   &PyBool_Type, &return_epot_per_bond, 
				   &PyBool_Type, &return_f_per_bond,
 				   &PyBool_Type, &return_wpot_per_at, 
				   &PyBool_Type, &return_wpot_per_bond))
    return NULL;

  epot = 0.0;

  dims[0] = data_get_len(a->f90data);
  dims[1] = 3;
  strides[0] = dims[1]*NPY_SIZEOF_DOUBLE;
  strides[1] = NPY_SIZEOF_DOUBLE;
  f = (PyObject*) PyArray_New(&PyArray_Type, 2, dims, NPY_DOUBLE, strides,
                              NULL, 0, NPY_FARRAY, NULL);
  memset(PyArray_DATA(f), 0, dims[0]*dims[1]*NPY_SIZEOF_DOUBLE);

  dims[0] = 3;
  dims[1] = 3;
  wpot = PyArray_ZEROS(2, dims, NPY_DOUBLE, 1);

  if (return_epot_per_at) {

    if (return_epot_per_at == Py_True) {
      dims[0] = data_get_len(a->f90data);
      epot_per_at = PyArray_ZEROS(1, dims, NPY_DOUBLE, 1);
      epot_per_at_ptr = PyArray_DATA(epot_per_at);
    } else {
      epot_per_at  = Py_None;
      Py_INCREF(Py_None);
    }

  }

  if (return_epot_per_bond) {

    if (return_epot_per_bond == Py_True) {
      dims[0] = get_neighbors_size(n, a);
      epot_per_bond = PyArray_ZEROS(1, dims, NPY_DOUBLE, 1);
      epot_per_bond_ptr = PyArray_DATA(epot_per_bond);
    } else {
      epot_per_bond = Py_None;
      Py_INCREF(Py_None);
    }

  }

  if (return_f_per_bond) {
    
    if (return_f_per_bond == Py_True) {
      dims[0] = get_neighbors_size(n, a);
      dims[1] = 3;
      strides[0] = dims[1]*NPY_SIZEOF_DOUBLE;
      strides[1] = NPY_SIZEOF_DOUBLE;
      f_per_bond = (PyObject*) PyArray_New(&PyArray_Type, 2, dims,
                                           NPY_DOUBLE, strides, NULL, 0,
                                           NPY_FARRAY, NULL);
      f_per_bond_ptr = PyArray_DATA(f_per_bond);
      memset(f_per_bond_ptr, 0, dims[0]*dims[1]*NPY_SIZEOF_DOUBLE);
    } else {
      f_per_bond  = Py_None;
      Py_INCREF(Py_None);
    }

  }

  if (return_wpot_per_at) {

    if (return_wpot_per_at == Py_True) {
      dims[0]            = data_get_len(a->f90data);
      dims[1]            = 3;
      dims[2]            = 3;
      strides[0]         = dims[1]*dims[2]*NPY_SIZEOF_DOUBLE;
      strides[1]         = dims[2]*NPY_SIZEOF_DOUBLE;
      strides[2]         = NPY_SIZEOF_DOUBLE;
      wpot_per_at      = (PyObject*) PyArray_New(&PyArray_Type, 3, dims,
						 NPY_DOUBLE, strides, NULL, 0,
						 NPY_FARRAY, NULL);
      wpot_per_at_ptr  = PyArray_DATA(wpot_per_at);
      memset(wpot_per_at_ptr, 0, dims[0]*dims[1]*dims[2]*NPY_SIZEOF_DOUBLE);
    } else {
      wpot_per_at  = Py_None;
      Py_INCREF(Py_None);
    }

  }

  if (return_wpot_per_bond) {

    if (return_wpot_per_bond == Py_True) {
      dims[0]            = get_neighbors_size(n, a);
      dims[1]            = 3;
      dims[2]            = 3;
      strides[0]         = dims[1]*dims[2]*NPY_SIZEOF_DOUBLE;
      strides[1]         = dims[2]*NPY_SIZEOF_DOUBLE;
      strides[2]         = NPY_SIZEOF_DOUBLE;
      wpot_per_bond      = (PyObject*) PyArray_New(&PyArray_Type, 3, dims,
						   NPY_DOUBLE, strides, NULL, 
						   0, NPY_FARRAY, NULL);
      wpot_per_bond_ptr  = PyArray_DATA(wpot_per_bond);
      memset(wpot_per_bond_ptr, 0, dims[0]*dims[1]*dims[2]*NPY_SIZEOF_DOUBLE);
    } else {
      wpot_per_bond  = Py_None;
      Py_INCREF(Py_None);
    }

  }

#ifdef DEBUG
  printf("[potential_energy_and_forces] self->f90class->name = %s\n",
	 self->f90class->name);
  printf("[potential_energy_and_forces] self->f90obj = %p\n",
	 self->f90obj);
  printf("[potential_energy_and_forces] a->f90obj = %p\n",
	 a->f90obj);
  printf("[potential_energy_and_forces] n->f90obj = %p\n",
	 n->f90obj);
  printf("[potential_energy_and_forces] self->f90class->energy_and_forces = %p\n",
	 self->f90class->energy_and_forces);
#endif

  self->f90class->energy_and_forces(self->f90obj, a->f90obj, n->f90obj,
				    &epot, PyArray_DATA(f), PyArray_DATA(wpot),
				    epot_per_at_ptr, epot_per_bond_ptr,
				    f_per_bond_ptr, wpot_per_at_ptr,
				    wpot_per_bond_ptr,
				    &ierror);

  /*
   * Now we need to reorder the per-bond properties such that some Python
   * script can actually make sense out of the data.
   */

  if (epot_per_bond_ptr) {
    dims[0] = get_number_of_all_neighbors(n, a);
    PyObject *tmp = PyArray_ZEROS(1, dims, NPY_DOUBLE, 1);

    f_pack_per_bond_scalar(n->f90obj, epot_per_bond_ptr, PyArray_DATA(tmp));

    Py_DECREF(epot_per_bond);
    epot_per_bond = tmp;
  }

  if (wpot_per_bond_ptr) {
    dims[0] = get_number_of_all_neighbors(n, a);
    dims[1] = 3;
    dims[2] = 3;
    PyObject *tmp = PyArray_ZEROS(3, dims, NPY_DOUBLE, 0);

    f_pack_per_bond_3x3(n->f90obj, wpot_per_bond_ptr, PyArray_DATA(tmp));

    Py_DECREF(wpot_per_bond);
    wpot_per_bond = tmp;
  }

#ifdef DEBUG
  printf("[potential_energy_and_forces] epot = %f\n", epot);
#endif

  if (error_to_py(ierror))
    return NULL;

  /* --- Compose return tuple --- */

  i = 3;
  if (epot_per_at)    i++;
  if (epot_per_bond)  i++;
  if (f_per_bond)     i++;
  if (wpot_per_at)    i++;
  if (wpot_per_bond)  i++;

  r  = PyTuple_New(i);
  if (!r)
    return NULL;

  PyTuple_SET_ITEM(r, 0, PyFloat_FromDouble(epot));
  PyTuple_SET_ITEM(r, 1, f);
  PyTuple_SET_ITEM(r, 2, wpot);

  i = 2;
  if (epot_per_at) {
    i++;
    PyTuple_SET_ITEM(r, i, epot_per_at);
  }
  if (epot_per_bond) {
    i++;
    PyTuple_SET_ITEM(r, i, epot_per_bond);
  }
  if (f_per_bond) {
    i++;
    PyTuple_SET_ITEM(r, i, f_per_bond);
  }
  if (wpot_per_at) {
    i++;
    PyTuple_SET_ITEM(r, i, wpot_per_at);
  }
  if (wpot_per_bond) {
    i++;
    PyTuple_SET_ITEM(r, i, wpot_per_bond);
  }

#ifdef DEBUG
  printf("{potential_energy_and_forces}\n");
#endif

  return r;
}
Exemple #3
0
static PyObject*
libtfr_stft(PyObject *self, PyObject *args)
{
        /* arguments */
        PyObject *o = NULL;
        PyArrayObject *signal = NULL;
        PyArrayObject *signal_cast = NULL;
        PyObject *o2 = NULL;
        PyArrayObject *window = NULL;
        int step;
        int N = 0;
        int Npoints, Ntapers;

        /* output data */
        npy_intp out_shape[3];
        PyArrayObject *outdata = NULL;
        int do_complex = 0;
        double *spec;
        complex double *zspec_tmp;
        npy_cdouble *zspec;

        /* internal stuff */
        mfft *mtmh;
        double *samples = NULL;
        double *windowp;

        /* parse arguments */
        if (!PyArg_ParseTuple(args, "OOi|ii", &o, &o2, &step, &N, &do_complex))
                return NULL;
        signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL);
        if (signal==NULL) {
                PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray");
                return NULL;
        }
        window = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 2, NPY_CONTIGUOUS, NULL);
        if (window==NULL) {
                PyErr_SetString(PyExc_TypeError, "Window must be a 1D or 2D ndarray");
                goto fail;
        }
        /* determine dimensions of window */
        if (PyArray_NDIM(window)==1) {
                Ntapers = 1;
                Npoints = PyArray_DIM(window, 0);
        }
        else {
                Ntapers = PyArray_DIM(window, 0);
                Npoints = PyArray_DIM(window, 1);
        }

        /* coerce data to proper type */
        samples = coerce_ndarray_double(signal, &signal_cast);
        if (samples==NULL) {
                PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type");
                goto fail;
        }
        /* need to copy the window function b/c mtm_destroy() will demalloc it */
        if (PyArray_TYPE(window)!=NPY_DOUBLE) {
                PyErr_SetString(PyExc_TypeError, "Window function must be double precision float");
                goto fail;
        }
        windowp = malloc(Npoints * Ntapers * sizeof(double));
        memcpy(windowp, PyArray_DATA(window), Npoints * Ntapers * sizeof(double));

        /* allocate outputs and do the transform */
        if (N < 1)
                N = Npoints;
        mtmh = mtm_init(N, Npoints, Ntapers, windowp, NULL);
        out_shape[0] = N/2+1;
        if (do_complex) {
                out_shape[1] = Ntapers;
                out_shape[2] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step);
                outdata  = (PyArrayObject*) PyArray_ZEROS(3,out_shape,NPY_CDOUBLE,1); // fortran-order
                zspec = (npy_cdouble*) PyArray_DATA(outdata);
                //printf("output dimensions: %d, %d, %d\n", out_shape[0], out_shape[1], out_shape[2]);
                zspec_tmp = (complex double*)malloc(PyArray_SIZE(outdata) * sizeof(complex double));
                mtm_zspec(mtmh, zspec_tmp, samples, PyArray_SIZE(signal), step);
                cmplx_c99tonpy(zspec_tmp, zspec, PyArray_SIZE(outdata));
                free(zspec_tmp);
        }
        else {
                out_shape[1] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step);
                outdata  = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // fortran-order
                spec = (double*) PyArray_DATA(outdata);
                mtm_spec(mtmh, spec, samples, PyArray_SIZE(signal), step, 0);
        }
        mtm_destroy(mtmh);

        Py_DECREF(signal);
        Py_DECREF(window);
        Py_XDECREF(signal_cast);
        return PyArray_Return(outdata);
fail:
        Py_XDECREF(signal_cast);
        Py_XDECREF(signal);
        Py_XDECREF(window);
        Py_XDECREF(outdata);
        return NULL;
}
Exemple #4
0
static PyObject*
transform (PyObject *dummy, PyObject *args)
{
    PyObject *intsarg=NULL;
    PyObject *orbitalsarg=NULL;
 
    PyObject *ints=NULL;
    PyObject *orbitals=NULL;
 
    if (!PyArg_ParseTuple(args, "OO", &intsarg, &orbitalsarg))
        return NULL;
 
    ints = PyArray_FROM_OTF(intsarg, NPY_DOUBLE, NPY_IN_ARRAY);
    if (ints == NULL)
        return NULL;
    int intsD = PyArray_NDIM(ints);
    if (intsD != 4)
    {
        printf("First input varaible must be a four dimensional array\n");
        return NULL;
    }
    int Nin = PyArray_DIM(ints, 0);
    for(int i = 0; i < intsD; i++)
    {
        if(PyArray_DIM(ints, i) != Nin)
        {
            printf("First input varaible must have all dimensions of the same size\n");
            return NULL;
        }
    }
 
    orbitals = PyArray_FROM_OTF(orbitalsarg, NPY_DOUBLE, NPY_IN_ARRAY);
    if (orbitals == NULL)
        return NULL;
    int orbitalsD = PyArray_NDIM(orbitals);
    if (orbitalsD != 2)
    {
        printf("Second input varaible must be two dimensional array\n");
        return NULL;
    }
    if (Nin != PyArray_DIM(orbitals, 0))
    {
        printf("Second input has wrong dimension. Does not fit to first varaible.\n");
        return NULL;        
    }
 
    int Nout = PyArray_DIM(orbitals, 1);
 
    //printf("Loaded integrals for basis size %d x %d.\n", Nin, Nout);
 
    npy_intp dims[4] = { Nout, Nout, Nout, Nout };
 
    PyObject* result = PyArray_ZEROS(4, dims, NPY_DOUBLE, 0);
 
    double* ints_data = PyArray_DATA(ints);
    double* orbitals_data = PyArray_DATA(orbitals);
    double* result_data = PyArray_DATA(result);
 
    for (int i = 0; i < Nout; ++i)
    {
        for (int j = i; j < Nout; ++j)
        {
        printf("i = %d j = %d\n", i, j);
            for (int k = i; k < Nout; ++k)
            {
                for (int l = k; l < Nout; ++l)
                {
                    if (abs(result_data[i * Nout * Nout * Nout + j * Nout * Nout + k * Nout + l]) < 1e-5)
                    {
                        double sum = 0;
                        for (int mu = 0; mu < Nin; ++mu)
                        {
                            for (int nu = 0; nu < Nin; ++nu)
                            {
                                for (int lamb = 0; lamb < Nin; ++lamb)
                                {
                                    for (int sigma = 0; sigma < Nin; ++sigma)
                                    {
                                        sum += 
                                        orbitals_data[mu * Nout + i] * 
                                        orbitals_data[nu * Nout + j] *
                                        ints_data[mu * Nin * Nin * Nin + nu * Nin * Nin + lamb * Nin + sigma] *
                                        orbitals_data[lamb * Nout + k] * 
                                        orbitals_data[sigma * Nout + l];
                                    }
                                }
                            }
                        }
                        result_data[i * Nout * Nout * Nout + j * Nout * Nout + k * Nout + l] = sum;                        
                        result_data[i * Nout * Nout * Nout + j * Nout * Nout + l * Nout + k] = sum;                        
 
                        result_data[j * Nout * Nout * Nout + i * Nout * Nout + k * Nout + l] = sum;                        
                        result_data[j * Nout * Nout * Nout + i * Nout * Nout + l * Nout + k] = sum;                        
 
                        result_data[k * Nout * Nout * Nout + l * Nout * Nout + i * Nout + j] = sum;                        
                        result_data[k * Nout * Nout * Nout + l * Nout * Nout + j * Nout + i] = sum;                        
 
                        result_data[l * Nout * Nout * Nout + k * Nout * Nout + i * Nout + j] = sum;                        
                        result_data[l * Nout * Nout * Nout + k * Nout * Nout + j * Nout + i] = sum;                        
 
                    }
                }
            }
        }
    }
 
    Py_DECREF(ints);
    Py_DECREF(orbitals);
 
    return result;
}