Beispiel #1
0
PyObject *
load_png_fast_progressive (char *filename,
                           PyObject *get_buffer_callback)
{
  // Note: we are not using the method that libpng calls "Reading PNG
  // files progressively". That method would involve feeding the data
  // into libpng piece by piece, which is not necessary if we can give
  // libpng a simple FILE pointer.

  png_structp png_ptr = NULL;
  png_infop info_ptr = NULL;
  PyObject * result = NULL;
  FILE *fp = NULL;
  uint32_t width, height;
  uint32_t rows_left;
  png_byte color_type;
  png_byte bit_depth;
  bool have_alpha;
  char *cm_processing = NULL;

  // ICC profile-based colour conversion data.
  png_charp icc_profile_name = NULL;
  int icc_compression_type = 0;
#if PNG_LIBPNG_VER < 10500    // 1.5.0beta36, according to libpng CHANGES
  png_charp icc_profile = NULL;
#else
  png_bytep icc_profile = NULL;
#endif
  png_uint_32 icc_proflen = 0;

  // The sRGB flag has an intent field, which we ignore - 
  // the target gamut is sRGB already.
  int srgb_intent = 0;

  // Generic RGB space conversion params.
  // The assumptions we're making are those of sRGB,
  // but they'll be overridden by gammas or primaries in the file if used.
  bool generic_rgb_have_gAMA = false;
  bool generic_rgb_have_cHRM = false;
  double generic_rgb_file_gamma = 45455 / PNG_gAMA_scale;
  double generic_rgb_white_x = 31270 / PNG_cHRM_scale;
  double generic_rgb_white_y = 32900 / PNG_cHRM_scale;
  double generic_rgb_red_x   = 64000 / PNG_cHRM_scale;
  double generic_rgb_red_y   = 33000 / PNG_cHRM_scale;
  double generic_rgb_green_x = 30000 / PNG_cHRM_scale;
  double generic_rgb_green_y = 60000 / PNG_cHRM_scale;
  double generic_rgb_blue_x  = 15000 / PNG_cHRM_scale;
  double generic_rgb_blue_y  =  6000 / PNG_cHRM_scale;

  // Indicates the case where no CM information was present in the file and we
  // treated it as sRGB.
  bool possible_legacy_png = false;

  // LCMS stuff
  cmsHPROFILE input_buffer_profile = NULL;
  cmsHPROFILE nparray_data_profile = cmsCreate_sRGBProfile();
  cmsHTRANSFORM input_buffer_to_nparray = NULL;
  cmsToneCurve *gamma_transfer_func = NULL;
  cmsUInt32Number input_buffer_format = 0;

  cmsSetLogErrorHandler(log_lcms2_error);

  fp = fopen(filename, "rb");
  if (!fp) {
    PyErr_SetFromErrno(PyExc_IOError);
    //PyErr_Format(PyExc_IOError, "Could not open PNG file for writing: %s",
    //             filename);
    goto cleanup;
  }

  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
                                    png_read_error_callback, NULL);
  if (!png_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_write_struct() failed");
    goto cleanup;
  }

  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_info_struct() failed");
    goto cleanup;
  }

  if (setjmp(png_jmpbuf(png_ptr))) {
    goto cleanup;
  }

  png_init_io(png_ptr, fp);

  png_read_info(png_ptr, info_ptr);

  // If there's an embedded ICC profile, use it in preference to any other
  // colour management information present.
  if (png_get_iCCP (png_ptr, info_ptr, &icc_profile_name,
                    &icc_compression_type, &icc_profile,
                    &icc_proflen))
  {
    input_buffer_profile = cmsOpenProfileFromMem(icc_profile, icc_proflen);
    if (! input_buffer_profile) {
      PyErr_SetString(PyExc_MemoryError, "cmsOpenProfileFromMem() failed");
      goto cleanup;
    }
    cm_processing = "iCCP (use embedded colour profile)";
  }

  // Shorthand for sRGB.
  else if (png_get_sRGB (png_ptr, info_ptr, &srgb_intent)) {
    input_buffer_profile = cmsCreate_sRGBProfile();
    cm_processing = "sRGB (explicit sRGB chunk)";
  }

  else {
    // We might have generic RGB transformation information in the form of
    // the chromaticities for R, G and B and a generic gamma curve.

    if (png_get_cHRM (png_ptr, info_ptr,
                      &generic_rgb_white_x, &generic_rgb_white_y,
                      &generic_rgb_red_x, &generic_rgb_red_y,
                      &generic_rgb_green_x, &generic_rgb_green_y,
                      &generic_rgb_blue_x, &generic_rgb_blue_y))
    {
      generic_rgb_have_cHRM = true;
    }
    if (png_get_gAMA(png_ptr, info_ptr, &generic_rgb_file_gamma)) {
      generic_rgb_have_gAMA = true;
    }
    if (generic_rgb_have_gAMA || generic_rgb_have_cHRM) {
      cmsCIExyYTRIPLE primaries = {{generic_rgb_red_x, generic_rgb_red_y},
                                   {generic_rgb_green_x, generic_rgb_green_y},
                                   {generic_rgb_blue_x, generic_rgb_blue_y}};
      cmsCIExyY white_point = {generic_rgb_white_x, generic_rgb_white_y};
      gamma_transfer_func = cmsBuildGamma(NULL, 1.0/generic_rgb_file_gamma);
      cmsToneCurve *transfer_funcs[3] = {gamma_transfer_func,
                                         gamma_transfer_func,
                                         gamma_transfer_func };
      input_buffer_profile = cmsCreateRGBProfile(&white_point, &primaries,
                                                transfer_funcs);
      cm_processing = "cHRM and/or gAMA (generic RGB space)";
    }

    // Possible legacy PNG, or rather one which might have been written with an
    // old version of MyPaint. Treat as sRGB, but flag the strangeness because
    // it might be important for PNGs in old OpenRaster files.
    else {
      possible_legacy_png = true;
      input_buffer_profile = cmsCreate_sRGBProfile();
      cm_processing = "sRGB (no CM chunks present)";
    }
  }

  if (png_get_interlace_type (png_ptr, info_ptr) != PNG_INTERLACE_NONE) {
    PyErr_SetString(PyExc_RuntimeError,
                    "Interlaced PNG files are not supported!");
    goto cleanup;
  }

  color_type = png_get_color_type(png_ptr, info_ptr);
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  have_alpha = color_type & PNG_COLOR_MASK_ALPHA;

  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(png_ptr);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(png_ptr);
  }

  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png_ptr);
    have_alpha = true;
  }

  if (bit_depth < 8) {
    png_set_packing(png_ptr);
  }

  if (!have_alpha) {
    png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(png_ptr);
  }

  png_read_update_info(png_ptr, info_ptr);

  // Verify what we have done
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  if (! (bit_depth == 8 || bit_depth == 16)) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to 8 or 16 bits per channel");
    goto cleanup;
  }
  if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB_ALPHA) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to RGBA (wrong color_type)");
    goto cleanup;
  }
  if (png_get_channels(png_ptr, info_ptr) != 4) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to RGBA (wrong number of channels)");
    goto cleanup;
  }

  // PNGs use network byte order, i.e. big-endian in descending order
  // of bit significance. LittleCMS uses whatever's detected for the compiler.
  // ref: http://www.w3.org/TR/2003/REC-PNG-20031110/#7Integers-and-byte-order
  if (bit_depth == 16) {
#ifdef CMS_USE_BIG_ENDIAN
    input_buffer_format = TYPE_RGBA_16;
#else
    input_buffer_format = TYPE_RGBA_16_SE;
#endif
  }
  else {
    input_buffer_format = TYPE_RGBA_8;
  }

  input_buffer_to_nparray = cmsCreateTransform
        (input_buffer_profile, input_buffer_format,
         nparray_data_profile, TYPE_RGBA_8,
         INTENT_PERCEPTUAL, 0);

  width = png_get_image_width(png_ptr, info_ptr);
  height = png_get_image_height(png_ptr, info_ptr);
  rows_left = height;

  while (rows_left) {
    PyObject *pyarr = NULL;
    uint32_t rows = 0;
    uint32_t row = 0;
    const uint8_t input_buf_bytes_per_pixel = (bit_depth==8) ? 4 : 8;
    const uint32_t input_buf_row_stride = sizeof(png_byte) * width
                                          * input_buf_bytes_per_pixel;
    png_byte *input_buffer = NULL;
    png_bytep *input_buf_row_pointers = NULL;

    pyarr = PyObject_CallFunction(get_buffer_callback, "ii", width, height);
    if (! pyarr) {
      PyErr_Format(PyExc_RuntimeError, "Get-buffer callback failed");
      goto cleanup;
    }
#ifdef HEAVY_DEBUG
    //assert(PyArray_ISCARRAY(arr));
    assert(PyArray_NDIM(pyarr) == 3);
    assert(PyArray_DIM(pyarr, 1) == width);
    assert(PyArray_DIM(pyarr, 2) == 4);
    assert(PyArray_TYPE(pyarr) == NPY_UINT8);
    assert(PyArray_ISBEHAVED(pyarr));
    assert(PyArray_STRIDE(pyarr, 1) == 4*sizeof(uint8_t));
    assert(PyArray_STRIDE(pyarr, 2) ==   sizeof(uint8_t));
#endif
    rows = PyArray_DIM(pyarr, 0);

    if (rows > rows_left) {
      PyErr_Format(PyExc_RuntimeError,
                   "Attempt to read %d rows from the PNG, "
                   "but only %d are left",
                   rows, rows_left);
      goto cleanup;
    }

    input_buffer = (png_byte *) malloc(rows * input_buf_row_stride);
    input_buf_row_pointers = (png_bytep *)malloc(rows * sizeof(png_bytep));
    for (row=0; row<rows; row++) {
      input_buf_row_pointers[row] = input_buffer + (row * input_buf_row_stride);
    }

    png_read_rows(png_ptr, input_buf_row_pointers, NULL, rows);
    rows_left -= rows;

    for (row=0; row<rows; row++) {
      uint8_t *pyarr_row = (uint8_t *)PyArray_DATA(pyarr)
                         + row*PyArray_STRIDE(pyarr, 0);
      uint8_t *input_row = input_buf_row_pointers[row];
      // Really minimal fake colour management. Just remaps to sRGB.
      cmsDoTransform(input_buffer_to_nparray, input_row, pyarr_row, width);
      // lcms2 ignores alpha, so copy that verbatim
      // If it's 8bpc RGBA, use A.
      // If it's 16bpc RrGgBbAa, use A.
      for (uint32_t i=0; i<width; ++i) {
        const uint32_t pyarr_alpha_byte = (i*4) + 3;
        const uint32_t buf_alpha_byte = (i*input_buf_bytes_per_pixel)
                                       + ((bit_depth==8) ? 3 : 6);
        pyarr_row[pyarr_alpha_byte] = input_row[buf_alpha_byte];
      }
    }

    free(input_buf_row_pointers);
    free(input_buffer);

    Py_DECREF(pyarr);
  }

  png_read_end(png_ptr, NULL);

  result = Py_BuildValue("{s:b,s:i,s:i,s:s}",
                         "possible_legacy_png", possible_legacy_png,
                         "width", width,
                         "height", height,
                         "cm_conversions_applied", cm_processing);

 cleanup:
  if (info_ptr) png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
  // libpng's style is to free internally allocated stuff like the icc
  // tables in png_destroy_*(). I think.
  if (fp) fclose(fp);
  if (input_buffer_profile) cmsCloseProfile(input_buffer_profile);
  if (nparray_data_profile) cmsCloseProfile(nparray_data_profile);
  if (input_buffer_to_nparray) cmsDeleteTransform(input_buffer_to_nparray);
  if (gamma_transfer_func) cmsFreeToneCurve(gamma_transfer_func);

  return result;
}
Beispiel #2
0
Py::Object
_path_module::point_in_path_collection(const Py::Tuple& args)
{
    args.verify_length(9);

    //segments, trans, clipbox, colors, linewidths, antialiaseds
    double                  x                = Py::Float(args[0]);
    double                  y                = Py::Float(args[1]);
    double                  radius           = Py::Float(args[2]);
    agg::trans_affine       master_transform = py_to_agg_transformation_matrix(args[3].ptr());
    Py::SeqBase<Py::Object> paths            = args[4];
    Py::SeqBase<Py::Object> transforms_obj   = args[5];
    Py::SeqBase<Py::Object> offsets_obj      = args[6];
    agg::trans_affine       offset_trans     = py_to_agg_transformation_matrix(args[7].ptr());
    bool                    filled           = Py::Int(args[8]);

    PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(
        offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
    if (!offsets ||
            (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
            (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
    {
        Py_XDECREF(offsets);
        throw Py::ValueError("Offsets array must be Nx2");
    }

    size_t Npaths      = paths.length();
    size_t Noffsets    = offsets->dimensions[0];
    size_t N           = std::max(Npaths, Noffsets);
    size_t Ntransforms = std::min(transforms_obj.length(), N);
    size_t i;

    // Convert all of the transforms up front
    typedef std::vector<agg::trans_affine> transforms_t;
    transforms_t transforms;
    transforms.reserve(Ntransforms);
    for (i = 0; i < Ntransforms; ++i)
    {
        agg::trans_affine trans = py_to_agg_transformation_matrix
                                  (transforms_obj[i].ptr(), false);
        trans *= master_transform;
        transforms.push_back(trans);
    }

    Py::List result;
    agg::trans_affine trans;

    for (i = 0; i < N; ++i)
    {
        PathIterator path(paths[i % Npaths]);

        if (Ntransforms)
        {
            trans = transforms[i % Ntransforms];
        }
        else
        {
            trans = master_transform;
        }

        if (Noffsets)
        {
            double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
            double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
            offset_trans.transform(&xo, &yo);
            trans *= agg::trans_affine_translation(xo, yo);
        }

        if (filled)
        {
            if (::point_in_path(x, y, path, trans))
                result.append(Py::Int((int)i));
        }
        else
        {
            if (::point_on_path(x, y, radius, path, trans))
                result.append(Py::Int((int)i));
        }
    }

    return result;
}
Beispiel #3
0
Py::Object
_path_module::update_path_extents(const Py::Tuple& args)
{
    args.verify_length(5);

    double x0, y0, x1, y1;
    PathIterator path(args[0]);
    agg::trans_affine trans = py_to_agg_transformation_matrix(
        args[1].ptr(), false);

    if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1))
    {
        throw Py::ValueError(
            "Must pass Bbox object as arg 3 of update_path_extents");
    }
    Py::Object minpos_obj = args[3];
    bool ignore = Py::Boolean(args[4]);

    double xm, ym;
    PyArrayObject* input_minpos = NULL;
    try
    {
        input_minpos = (PyArrayObject*)PyArray_FromObject(
            minpos_obj.ptr(), PyArray_DOUBLE, 1, 1);
        if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2)
        {
            throw Py::TypeError(
                "Argument 4 to update_path_extents must be a length-2 numpy array.");
        }
        xm = *(double*)PyArray_GETPTR1(input_minpos, 0);
        ym = *(double*)PyArray_GETPTR1(input_minpos, 1);
    }
    catch (...)
    {
        Py_XDECREF(input_minpos);
        throw;
    }
    Py_XDECREF(input_minpos);

    npy_intp extent_dims[] = { 2, 2, 0 };
    double* extents_data = NULL;
    npy_intp minpos_dims[] = { 2, 0 };
    double* minpos_data = NULL;
    PyArrayObject* extents = NULL;
    PyArrayObject* minpos = NULL;
    bool changed = false;

    try
    {
        extents = (PyArrayObject*)PyArray_SimpleNew
                  (2, extent_dims, PyArray_DOUBLE);
        if (extents == NULL)
        {
            throw Py::MemoryError("Could not allocate result array");
        }
        minpos = (PyArrayObject*)PyArray_SimpleNew
                 (1, minpos_dims, PyArray_DOUBLE);
        if (minpos == NULL)
        {
            throw Py::MemoryError("Could not allocate result array");
        }

        extents_data = (double*)PyArray_DATA(extents);
        minpos_data = (double*)PyArray_DATA(minpos);

        if (ignore)
        {
            extents_data[0] = std::numeric_limits<double>::infinity();
            extents_data[1] = std::numeric_limits<double>::infinity();
            extents_data[2] = -std::numeric_limits<double>::infinity();
            extents_data[3] = -std::numeric_limits<double>::infinity();
            minpos_data[0] = std::numeric_limits<double>::infinity();
            minpos_data[1] = std::numeric_limits<double>::infinity();
        }
        else
        {
            if (x0 > x1)
            {
                extents_data[0] = std::numeric_limits<double>::infinity();
                extents_data[2] = -std::numeric_limits<double>::infinity();
            }
            else
            {
                extents_data[0] = x0;
                extents_data[2] = x1;
            }
            if (y0 > y1)
            {
                extents_data[1] = std::numeric_limits<double>::infinity();
                extents_data[3] = -std::numeric_limits<double>::infinity();
            }
            else
            {
                extents_data[1] = y0;
                extents_data[3] = y1;
            }
            minpos_data[0] = xm;
            minpos_data[1] = ym;
        }

        ::get_path_extents(path, trans, &extents_data[0], &extents_data[1],
                           &extents_data[2], &extents_data[3], &minpos_data[0],
                           &minpos_data[1]);

        changed = (extents_data[0] != x0 ||
                   extents_data[1] != y0 ||
                   extents_data[2] != x1 ||
                   extents_data[3] != y1 ||
                   minpos_data[0]  != xm ||
                   minpos_data[1]  != ym);

    }
    catch (...)
    {
        Py_XDECREF(extents);
        Py_XDECREF(minpos);
        throw;
    }

    Py::Tuple result(3);
    result[0] = Py::Object((PyObject*) extents);
    result[1] = Py::Object((PyObject*) minpos);
    result[2] = Py::Int(changed ? 1 : 0);

    Py_XDECREF(extents);
    Py_XDECREF(minpos);

    return result;
}
Beispiel #4
0
PyObject *
py_pair_distribution(PyObject *self, PyObject *args)
{
  PyObject *i_arr, *r_arr;
  int nbins;
  double cutoff;

  if (!PyArg_ParseTuple(args, "O!O!id", &PyArray_Type, &i_arr,
			&PyArray_Type, &r_arr, &nbins, &cutoff))
    return NULL;

  if (PyArray_NDIM(i_arr) != 1 || PyArray_TYPE(i_arr) != NPY_INT) {
    PyErr_SetString(PyExc_TypeError, "First argument needs to be "
                    "one-dimensional integer array.");
    return NULL;
  }
  if (PyArray_NDIM(r_arr) != 1 || PyArray_TYPE(r_arr) != NPY_DOUBLE) {
    PyErr_SetString(PyExc_TypeError, "Second argument needs to be "
                    "one-dimensional double array.");
    return NULL;
  }

  npy_intp npairs = PyArray_DIM(i_arr, 0);
  if (PyArray_DIM(r_arr, 0) != npairs) {
    PyErr_SetString(PyExc_RuntimeError, "First two arguments need to be arrays "
                    "of identical length.");
    return NULL;
  }

  npy_intp dim = nbins;
  PyObject *h_arr = PyArray_ZEROS(1, &dim, NPY_DOUBLE, 1);
  PyObject *h2_arr = PyArray_ZEROS(1, &dim, NPY_DOUBLE, 1);
  PyObject *tmp_arr = PyArray_ZEROS(1, &dim, NPY_INT, 1);

  npy_int *i = PyArray_DATA(i_arr);
  double *r = PyArray_DATA(r_arr);
  double *h = PyArray_DATA(h_arr);
  double *h2 = PyArray_DATA(h2_arr);
  npy_int *tmp = PyArray_DATA(tmp_arr);

  npy_int last_i = i[0];
  memset(tmp, 0, nbins*sizeof(npy_int));
  int nat = 1, p;
  for (p = 0; p < npairs; p++) {
    if (last_i != i[p]) {
      int bin;
      for (bin = 0; bin < nbins; bin++) {
	h[bin] += tmp[bin];
	h2[bin] += tmp[bin]*tmp[bin];
      }
      memset(tmp, 0, nbins*sizeof(npy_int));
      last_i = i[p];
      nat++;
    }

    int bin = (int) (nbins*r[p]/cutoff);
    if (bin >= 0 && bin < nbins) {
      tmp[bin]++;
    }
  }
  int bin;
  for (bin = 0; bin < nbins; bin++) {
    h[bin] += tmp[bin];
    h2[bin] += tmp[bin]*tmp[bin];

    double r1 = bin*cutoff/nbins, r2 = (bin+1)*cutoff/nbins;
    double binvol = 4*M_PI/3*(r2*r2*r2 - r1*r1*r1);

    h[bin] /= nat*binvol;
    h2[bin] /= nat*binvol*binvol;
    h2[bin] -= h[bin]*h[bin];
  }

  Py_DECREF(tmp_arr);

  return Py_BuildValue("OO", h_arr, h2_arr);
}
Beispiel #5
0
Py::Object TriModule::new_triangulation(const Py::Tuple &args)
{
    _VERBOSE("TriModule::new_triangulation");
    args.verify_length(6);

    // x and y.
    PyArrayObject* x = (PyArrayObject*)PyArray_ContiguousFromObject(
                           args[0].ptr(), PyArray_DOUBLE, 1, 1);
    PyArrayObject* y = (PyArrayObject*)PyArray_ContiguousFromObject(
                           args[1].ptr(), PyArray_DOUBLE, 1, 1);
    if (x == 0 || y == 0 || PyArray_DIM(x,0) != PyArray_DIM(y,0)) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        throw Py::ValueError("x and y must be 1D arrays of the same length");
    }

    // triangles.
    PyArrayObject* triangles = (PyArrayObject*)PyArray_ContiguousFromObject(
                                   args[2].ptr(), PyArray_INT, 2, 2);
    if (triangles == 0 || PyArray_DIM(triangles,1) != 3) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(triangles);
        throw Py::ValueError("triangles must be a 2D array of shape (?,3)");
    }

    // Optional mask.
    PyArrayObject* mask = 0;
    if (args[3].ptr() != 0 && args[3] != Py::None())
    {
        mask = (PyArrayObject*)PyArray_ContiguousFromObject(
                   args[3].ptr(), PyArray_BOOL, 1, 1);
        if (mask == 0 || PyArray_DIM(mask,0) != PyArray_DIM(triangles,0)) {
            Py_XDECREF(x);
            Py_XDECREF(y);
            Py_XDECREF(triangles);
            Py_XDECREF(mask);
            throw Py::ValueError(
                "mask must be a 1D array with the same length as the triangles array");
        }
    }

    // Optional edges.
    PyArrayObject* edges = 0;
    if (args[4].ptr() != 0 && args[4] != Py::None())
    {
        edges = (PyArrayObject*)PyArray_ContiguousFromObject(
                    args[4].ptr(), PyArray_INT, 2, 2);
        if (edges == 0 || PyArray_DIM(edges,1) != 2) {
            Py_XDECREF(x);
            Py_XDECREF(y);
            Py_XDECREF(triangles);
            Py_XDECREF(mask);
            Py_XDECREF(edges);
            throw Py::ValueError("edges must be a 2D array with shape (?,2)");
        }
    }

    // Optional neighbors.
    PyArrayObject* neighbors = 0;
    if (args[5].ptr() != 0 && args[5] != Py::None())
    {
        neighbors = (PyArrayObject*)PyArray_ContiguousFromObject(
                        args[5].ptr(), PyArray_INT, 2, 2);
        if (neighbors == 0 ||
            PyArray_DIM(neighbors,0) != PyArray_DIM(triangles,0) ||
            PyArray_DIM(neighbors,1) != PyArray_DIM(triangles,1)) {
            Py_XDECREF(x);
            Py_XDECREF(y);
            Py_XDECREF(triangles);
            Py_XDECREF(mask);
            Py_XDECREF(edges);
            Py_XDECREF(neighbors);
            throw Py::ValueError(
                "neighbors must be a 2D array with the same shape as the triangles array");
        }
    }

    return Py::asObject(new Triangulation(x, y, triangles, mask, edges, neighbors));
}
Beispiel #6
0
static PyObject* ccdToQ(PyObject *self, PyObject *args, PyObject *kwargs){
  static char *kwlist[] = { "angles", "mode", "ccd_size", "ccd_pixsize", 
			    "ccd_cen", "dist", "wavelength", 
			    "UBinv", "outarray", NULL };
  PyObject *angles = NULL;
  PyObject *_angles = NULL;
  PyObject *_ubinv = NULL;
  PyObject *ubinv = NULL;
  PyObject *_outarray = NULL;
  PyObject *qOut = NULL;
  CCD ccd;
  npy_intp dims[2];
  npy_intp nimages;
  int i, j, t, stride;
  int ndelgam;
  int mode;

  _float lambda;

  _float *anglesp;
  _float *qOutp;
  _float *ubinvp;
  _float UBI[3][3];

#ifdef USE_THREADS
  pthread_t thread[NTHREADS];
  int iret[NTHREADS];
#endif
  imageThreadData threadData[NTHREADS];

  if(!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi(ii)(dd)(dd)ddO|O", kwlist,
				  &_angles,
				  &mode,
				  &ccd.xSize, &ccd.ySize,
				  &ccd.xPixSize, &ccd.yPixSize, 
				  &ccd.xCen, &ccd.yCen,
				  &ccd.dist,
				  &lambda,
				  &_ubinv,
				  &_outarray)){
    return NULL;
  }

  angles = PyArray_FROMANY(_angles, NPY_DOUBLE, 2, 2, NPY_IN_ARRAY);
  if(!angles){
    PyErr_SetString(PyExc_ValueError, "angles must be a 2-D array of floats");
    goto cleanup;
  }
  
  ubinv = PyArray_FROMANY(_ubinv, NPY_DOUBLE, 2, 2, NPY_IN_ARRAY);
  if(!ubinv){
    PyErr_SetString(PyExc_ValueError, "ubinv must be a 2-D array of floats");
    goto cleanup;
  }

  ubinvp = (_float *)PyArray_DATA(ubinv);
  for(i=0;i<3;i++){
    UBI[i][0] = -1.0 * ubinvp[2];
    UBI[i][1] = ubinvp[1];
    UBI[i][2] = ubinvp[0];
    ubinvp+=3;
  }
  
  nimages = PyArray_DIM(angles, 0);
  ndelgam = ccd.xSize * ccd.ySize;

  dims[0] = nimages * ndelgam;
  dims[1] = 4;
  if(!_outarray){
    // Create new numpy array
    // fprintf(stderr, "**** Creating new array\n");
    qOut = PyArray_SimpleNew(2, dims, NPY_DOUBLE);
    if(!qOut){
      goto cleanup;
    }
  } else {
    qOut = PyArray_FROMANY(_outarray, NPY_DOUBLE, 2, 2, NPY_INOUT_ARRAY);
    if(!qOut){
      PyErr_SetString(PyExc_ValueError, "outarray must be a 2-D array of floats");
      goto cleanup;
    }
    if(PyArray_Size(qOut) != (4 * nimages * ndelgam)){
      PyErr_SetString(PyExc_ValueError, "outarray is of the wrong size");
      goto cleanup;
    }
  }
  anglesp = (_float *)PyArray_DATA(angles);
  qOutp = (_float *)PyArray_DATA(qOut);

  stride = nimages / NTHREADS;
  for(t=0;t<NTHREADS;t++){
    // Setup threads
    // Allocate memory for delta/gamma pairs
    
    threadData[t].ccd = &ccd;
    threadData[t].anglesp = anglesp;
    threadData[t].qOutp = qOutp;
    threadData[t].ndelgam = ndelgam;
    threadData[t].lambda = lambda;
    threadData[t].mode = mode;
    threadData[t].imstart = stride * t;
    for(i=0;i<3;i++){
      for(j=0;j<3;j++){
	threadData[t].UBI[j][i] = UBI[j][i];
      }
    }
    if(t == (NTHREADS - 1)){
      threadData[t].imend = nimages;
    } else {
      threadData[t].imend = stride * (t + 1);
    }

#ifdef USE_THREADS
    iret[t] = pthread_create( &thread[t], NULL, 
			      processImageThread, 
			      (void*) &threadData[t]);
#else
    processImageThread((void *) &threadData[t]);
#endif
    anglesp += (6 * stride);
    qOutp += (ndelgam * 4 * stride);
  }

#ifdef USE_THREADS
  for(t=0;t<NTHREADS;t++){
    if(pthread_join(thread[t], NULL)){
      fprintf(stderr, "ERROR : Cannot join thread %d", t);
    }
  }
#endif

  Py_XDECREF(ubinv);
  Py_XDECREF(angles);
  return Py_BuildValue("N", qOut);

 cleanup:
  Py_XDECREF(ubinv);
  Py_XDECREF(angles);
  Py_XDECREF(qOut);
  return NULL;
}
Beispiel #7
0
int array_levinson_nd(PyArrayObject *arr, long order,
                      PyArrayObject** alpccoeff,
                      PyArrayObject **klpccoeff, PyArrayObject **elpc)
{
	double *acoeff, *kcoeff, *tmp;
	double *err;
	double *data;
	npy_int rank;
	npy_intp alpc_size[NPY_MAXDIMS];
	npy_intp klpc_size[NPY_MAXDIMS];
	npy_intp elpc_size[NPY_MAXDIMS];
	npy_int n, nrepeat;
	int i;

	rank = PyArray_NDIM(arr);
	if (rank < 2) {
		return -1;
	}

	nrepeat = 1;
	for (i = 0; i < rank - 1; ++i) {
		nrepeat *= PyArray_DIM(arr, i);
		alpc_size[i] = PyArray_DIM(arr, i);
		klpc_size[i] = PyArray_DIM(arr, i);
		elpc_size[i] = PyArray_DIM(arr, i);
	}
	alpc_size[rank-1] = order + 1;
	klpc_size[rank-1] = order;

	*alpccoeff = (PyArrayObject*)PyArray_SimpleNew(rank, alpc_size,
                                                       PyArray_DOUBLE);
        if(*alpccoeff == NULL) {
                return -1;
        }

	*klpccoeff = (PyArrayObject*)PyArray_SimpleNew(rank, klpc_size,
						       NPY_DOUBLE);
        if(*klpccoeff == NULL) {
                goto clean_alpccoeff;
        }

        *elpc = (PyArrayObject*)PyArray_SimpleNew(rank-1, elpc_size, NPY_DOUBLE);
        if(*elpc == NULL) {
                goto clean_klpccoeff;
        }

	tmp = malloc(sizeof(*tmp) * order);
	if (tmp == NULL) {
                goto clean_elpc;
	}

	data = (double*)arr->data;
	acoeff = (double*)((*alpccoeff)->data);
	kcoeff = (double*)((*klpccoeff)->data);
	err = (double*)((*elpc)->data);
	n = PyArray_DIM(arr, rank-1);
	for(i = 0; i < nrepeat; ++i) {
		levinson(data, order, acoeff, err, kcoeff, tmp);
		data += n;
		acoeff += order + 1;
		kcoeff += order;
		err += 1;
	}

        free(tmp);
        return 0;

clean_elpc:
        Py_DECREF(*elpc);
clean_klpccoeff:
        Py_DECREF(*klpccoeff);
clean_alpccoeff:
        Py_DECREF(*alpccoeff);
	return -1;
}
Beispiel #8
0
static PyObject *cs_gamma_findzofA(PyObject *self, PyObject *args)
{
  PyArrayObject *Numpy_amp;
  PyObject *Numpy_zofA;
  double Gmu, alpha, *zofA, *amp;
  unsigned long int Namp;
  (void)self;	/* silence unused parameter warning */

  double z_min = 1e-20, z_max = 1e10;
  double dlnz = 0.05;
  unsigned numz = floor( (log(z_max) - log(z_min)) / dlnz );
  unsigned long int i;
  cs_cosmo_functions_t cosmofns;
  double *fz,*z;
  double a;
  gsl_interp *zofa_interp;
  gsl_interp_accel *acc_zofa = gsl_interp_accel_alloc();

  if (!PyArg_ParseTuple(args, "ddO!", &Gmu, &alpha, &PyArray_Type, &Numpy_amp))
    return NULL;

  Numpy_amp = PyArray_GETCONTIGUOUS(Numpy_amp);
  if(!Numpy_amp)
    return NULL;
  Namp = PyArray_DIM(Numpy_amp, 0);
  amp = PyArray_DATA(Numpy_amp);

  {
  npy_intp dims[1] = {Namp};
  Numpy_zofA = PyArray_SimpleNew(1, dims, NPY_DOUBLE);
  }
  zofA = PyArray_DATA((PyArrayObject *) Numpy_zofA);

  cosmofns = XLALCSCosmoFunctionsAlloc( z_min, dlnz, numz );

  zofa_interp = gsl_interp_alloc (gsl_interp_linear, cosmofns.n);

  fz = calloc( cosmofns.n, sizeof( *fz ) );
  z = calloc( cosmofns.n, sizeof( *z ) );

  /* first compute the function that relates A and z */
  /* invert order; b/c fz is a monotonically decreasing func of z */
  for ( i = cosmofns.n ; i > 0; i-- )
    {
      unsigned long int j = cosmofns.n - i;
      z[j] = cosmofns.z[i-1];
      fz[j] = pow(cosmofns.phit[i-1], 2.0/3.0) * pow(1+z[j], -1.0/3.0) / cosmofns.phiA[i-1];
    }

  gsl_interp_init (zofa_interp, fz, z, cosmofns.n);

  /* now compute the amplitudes (suitably multiplied) that are equal to fz for some z*/
  for ( i = 0; i < Namp; i++ )
    {
      a = amp[i] * pow(H0,-1.0/3.0) * pow(alpha,-2.0/3.0) / Gmu;
      /* evaluate z(fz) at fz=a */
      zofA[i] = gsl_interp_eval (zofa_interp, fz, z, a, acc_zofa );
      if(gsl_isnan(zofA[i])) {
        Py_DECREF(Numpy_zofA);
        Numpy_zofA = NULL;
        break;
      }
    }

  XLALCSCosmoFunctionsFree( cosmofns );
  Py_DECREF(Numpy_amp);
  free(fz);
  free(z);
  gsl_interp_free (zofa_interp);
  gsl_interp_accel_free(acc_zofa);

  return Numpy_zofA;
}
Beispiel #9
0
/*
 * digitize(x, bins, right=False) returns an array of integers the same length
 * as x. The values i returned are such that bins[i - 1] <= x < bins[i] if
 * bins is monotonically increasing, or bins[i - 1] > x >= bins[i] if bins
 * is monotonically decreasing.  Beyond the bounds of bins, returns either
 * i = 0 or i = len(bins) as appropriate. If right == True the comparison
 * is bins [i - 1] < x <= bins[i] or bins [i - 1] >= x > bins[i]
 */
NPY_NO_EXPORT PyObject *
arr_digitize(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds)
{
    PyObject *obj_x = NULL;
    PyObject *obj_bins = NULL;
    PyArrayObject *arr_x = NULL;
    PyArrayObject *arr_bins = NULL;
    PyObject *ret = NULL;
    npy_intp len_bins;
    int monotonic, right = 0;
    NPY_BEGIN_THREADS_DEF

    static char *kwlist[] = {"x", "bins", "right", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|i", kwlist,
                                     &obj_x, &obj_bins, &right)) {
        goto fail;
    }

    /* PyArray_SearchSorted will make `x` contiguous even if we don't */
    arr_x = (PyArrayObject *)PyArray_FROMANY(obj_x, NPY_DOUBLE, 0, 0,
                                             NPY_ARRAY_CARRAY_RO);
    if (arr_x == NULL) {
        goto fail;
    }

    /* TODO: `bins` could be strided, needs change to check_array_monotonic */
    arr_bins = (PyArrayObject *)PyArray_FROMANY(obj_bins, NPY_DOUBLE, 1, 1,
                                               NPY_ARRAY_CARRAY_RO);
    if (arr_bins == NULL) {
        goto fail;
    }

    len_bins = PyArray_SIZE(arr_bins);
    if (len_bins == 0) {
        PyErr_SetString(PyExc_ValueError, "bins must have non-zero length");
        goto fail;
    }

    NPY_BEGIN_THREADS_THRESHOLDED(len_bins)
    monotonic = check_array_monotonic((const double *)PyArray_DATA(arr_bins),
                                      len_bins);
    NPY_END_THREADS

    if (monotonic == 0) {
        PyErr_SetString(PyExc_ValueError,
                        "bins must be monotonically increasing or decreasing");
        goto fail;
    }

    /* PyArray_SearchSorted needs an increasing array */
    if (monotonic == - 1) {
        PyArrayObject *arr_tmp = NULL;
        npy_intp shape = PyArray_DIM(arr_bins, 0);
        npy_intp stride = -PyArray_STRIDE(arr_bins, 0);
        void *data = (void *)(PyArray_BYTES(arr_bins) - stride * (shape - 1));

        arr_tmp = (PyArrayObject *)PyArray_New(&PyArray_Type, 1, &shape,
                                               NPY_DOUBLE, &stride, data, 0,
                                               PyArray_FLAGS(arr_bins), NULL);
        if (!arr_tmp) {
            goto fail;
        }

        if (PyArray_SetBaseObject(arr_tmp, (PyObject *)arr_bins) < 0) {

            Py_DECREF(arr_tmp);
            goto fail;
        }
        arr_bins = arr_tmp;
    }

    ret = PyArray_SearchSorted(arr_bins, (PyObject *)arr_x,
                               right ? NPY_SEARCHLEFT : NPY_SEARCHRIGHT, NULL);
    if (!ret) {
        goto fail;
    }

    /* If bins is decreasing, ret has bins from end, not start */
    if (monotonic == -1) {
        npy_intp *ret_data =
                        (npy_intp *)PyArray_DATA((PyArrayObject *)ret);
        npy_intp len_ret = PyArray_SIZE((PyArrayObject *)ret);

        NPY_BEGIN_THREADS_THRESHOLDED(len_ret)
        while (len_ret--) {
            *ret_data = len_bins - *ret_data;
            ret_data++;
        }
        NPY_END_THREADS
    }
Beispiel #10
0
static PyObject *sky_map_toa_phoa_snr(
    PyObject *NPY_UNUSED(module), PyObject *args, PyObject *kwargs)
{
    /* Input arguments */
    long nside = -1;
    long npix;
    double min_distance;
    double max_distance;
    int prior_distance_power;
    double gmst;
    unsigned int nifos;
    unsigned long nsamples = 0;
    double sample_rate;
    PyObject *acors_obj;
    PyObject *responses_obj;
    PyObject *locations_obj;
    PyObject *horizons_obj;
    PyObject *toas_obj;
    PyObject *phoas_obj;
    PyObject *snrs_obj;

    /* Names of arguments */
    static const char *keywords[] = {"min_distance", "max_distance",
        "prior_distance_power", "gmst", "sample_rate", "acors", "responses",
        "locations", "horizons", "toas", "phoas", "snrs", "nside", NULL};

    /* Parse arguments */
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddiddOOOOOOO|l",
        keywords, &min_distance, &max_distance, &prior_distance_power, &gmst,
        &sample_rate, &acors_obj, &responses_obj, &locations_obj,
        &horizons_obj, &toas_obj, &phoas_obj, &snrs_obj, &nside)) return NULL;

    /* Determine HEALPix resolution, if specified */
    if (nside == -1)
    {
        npix = -1;
    } else {
        npix = nside2npix(nside);
        if (npix == -1)
        {
            PyErr_SetString(PyExc_ValueError, "nside must be a power of 2");
            return NULL;
        }
    }

    /* Determine number of detectors */
    {
        Py_ssize_t n = PySequence_Length(acors_obj);
        if (n < 0) return NULL;
        nifos = n;
    }

    /* Return value */
    PyObject *out = NULL;

    /* Numpy array objects */
    PyArrayObject *acors_npy[nifos], *responses_npy[nifos],
        *locations_npy[nifos], *horizons_npy = NULL, *toas_npy = NULL,
        *phoas_npy = NULL, *snrs_npy = NULL;
    memset(acors_npy, 0, sizeof(acors_npy));
    memset(responses_npy, 0, sizeof(responses_npy));
    memset(locations_npy, 0, sizeof(locations_npy));

    /* Arrays of pointers for inputs with multiple dimensions */
    const double complex *acors[nifos];
    const float (*responses[nifos])[3];
    const double *locations[nifos];

    /* Gather C-aligned arrays from Numpy types */
    INPUT_LIST_OF_ARRAYS(acors, NPY_CDOUBLE, 1,
        npy_intp dim = PyArray_DIM(npy, 0);
        if (iifo == 0)
            nsamples = dim;
        else if ((unsigned long)dim != nsamples)
        {
            PyErr_SetString(PyExc_ValueError,
                "expected elements of acors to be vectors of the same length");
            goto fail;
        }
    )
Beispiel #11
0
static PyObject* py_fitexpsin(PyObject *obj, PyObject *args, PyObject *kwds)
{
    PyArrayObject *data = NULL;
    PyArrayObject *fitt = NULL;
    PyArrayObject *rslt = NULL;
    PyArrayIterObject *data_it = NULL;
    PyArrayIterObject *fitt_it = NULL;
    PyArrayIterObject *rslt_it = NULL;
    Py_ssize_t newshape[NPY_MAXDIMS];
    double *poly = NULL;
    double *coef = NULL;
    double *buff = NULL;
    int i, j, error, lastaxis, numdata;
    int startcoef = -1;
    int numcoef = MAXCOEF;
    int axis = NPY_MAXDIMS;
    double deltat = 1.0;
    static char *kwlist[] = {"data", "numcoef",
                             "deltat", "axis", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|idO&", kwlist,
        PyConverter_AnyDoubleArray, &data, &numcoef, &deltat,
        PyArray_AxisConverter, &axis)) return NULL;

    if (axis < 0) {
        axis += PyArray_NDIM(data);
    }
    if ((axis < 0) || (axis >= NPY_MAXDIMS)) {
        PyErr_Format(PyExc_ValueError, "invalid axis");
        goto _fail;
    }
    lastaxis = PyArray_NDIM(data) - 1;

    if ((numcoef < 1) || (numcoef > MAXCOEF)) {
        PyErr_Format(PyExc_ValueError, "numcoef out of bounds");
        goto _fail;
    }

    if (startcoef < 0) { /* start regression away from zero coefficients */
        startcoef = 4;
    }
    if (startcoef > numcoef - 2) {
        PyErr_Format(PyExc_ValueError, "startcoef out of bounds");
        goto _fail;
    }

    numdata = (int)PyArray_DIM(data, axis);
    if (numcoef > numdata)
        numcoef = numdata;

    if ((numcoef - startcoef - 1) < 3) {
        PyErr_Format(PyExc_ValueError,
            "number of coefficients insufficient to fit data");
        goto _fail;
    }

    /* fitted data */
    fitt = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(data),
                                              PyArray_DIMS(data), NPY_DOUBLE);
    if (fitt == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate fitt array");
        goto _fail;
    }

    /* fitted parameters */
    j = 0;
    for (i = 0; i < PyArray_NDIM(data); i++) {
        if (i != axis)
            newshape[j++] = PyArray_DIM(data, i);
    }
    newshape[j] = 5;
    rslt = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(data),
                                              newshape, NPY_DOUBLE);
    if (rslt == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate rslt array");
        goto _fail;
    }

    /* working buffer */
    buff = (double *)PyMem_Malloc(3*numdata * sizeof(double));
    if (buff == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate buff array");
        goto _fail;
    }

    /* buffer for differential coefficients */
    coef = (double *)PyMem_Malloc((3+1)*(numcoef+1) * sizeof(double));
    if (coef == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate coef array");
        goto _fail;
    }

    /* precalculate normalized Chebyshev polynomial */
    poly = (double *)PyMem_Malloc(numdata * (numcoef+1) * sizeof(double));
    if (poly == NULL) {
        PyErr_Format(PyExc_MemoryError, "unable to allocate poly");
        goto _fail;
    }

    error = chebypoly(numdata, numcoef, poly, 1);
    if (error != 0) {
        PyErr_Format(PyExc_ValueError,
            "chebypoly() failed with error code %i", error);
        goto _fail;
    }

    /* iterate over all but specified axis */
    data_it = (PyArrayIterObject *)PyArray_IterAllButAxis(
                                            (PyObject *)data, &axis);
    fitt_it = (PyArrayIterObject *)PyArray_IterAllButAxis(
                                            (PyObject *)fitt, &axis);
    rslt_it = (PyArrayIterObject *)PyArray_IterAllButAxis(
                                            (PyObject *)rslt, &lastaxis);

    while (data_it->index < data_it->size) {
        error = fitexpsin(
            (char *)data_it->dataptr,
            (int)PyArray_STRIDE(data, axis),
            numdata,
            poly,
            coef,
            numcoef,
            deltat,
            startcoef,
            buff,
            (double *)rslt_it->dataptr,
            (char *)fitt_it->dataptr,
            (int)PyArray_STRIDE(fitt, axis));

        if (error != 0) {
            PyErr_Format(PyExc_ValueError,
                "fitexpsin() failed with error code %i", error);
            goto _fail;
        }

        PyArray_ITER_NEXT(data_it);
        PyArray_ITER_NEXT(fitt_it);
        PyArray_ITER_NEXT(rslt_it);
    }

    Py_XDECREF(data_it);
    Py_XDECREF(fitt_it);
    Py_XDECREF(rslt_it);
    Py_XDECREF(data);
    PyMem_Free(poly);
    PyMem_Free(coef);
    PyMem_Free(buff);

    return Py_BuildValue("(N, N)", rslt, fitt);

  _fail:
    Py_XDECREF(data_it);
    Py_XDECREF(fitt_it);
    Py_XDECREF(rslt_it);
    Py_XDECREF(data);
    Py_XDECREF(fitt);
    Py_XDECREF(rslt);
    PyMem_Free(poly);
    PyMem_Free(coef);
    PyMem_Free(buff);

    return NULL;
}
Beispiel #12
0
    const double *locations[nifos];

    /* Gather C-aligned arrays from Numpy types */
    INPUT_LIST_OF_ARRAYS(acors, NPY_CDOUBLE, 1,
        npy_intp dim = PyArray_DIM(npy, 0);
        if (iifo == 0)
            nsamples = dim;
        else if ((unsigned long)dim != nsamples)
        {
            PyErr_SetString(PyExc_ValueError,
                "expected elements of acors to be vectors of the same length");
            goto fail;
        }
    )
    INPUT_LIST_OF_ARRAYS(responses, NPY_FLOAT, 2,
        if (PyArray_DIM(npy, 0) != 3 || PyArray_DIM(npy, 1) != 3)
        {
            PyErr_SetString(PyExc_ValueError,
                "expected elements of responses to be 3x3 arrays");
            goto fail;
        }
    )
    INPUT_LIST_OF_ARRAYS(locations, NPY_DOUBLE, 1,
        if (PyArray_DIM(npy, 0) != 3)
        {
            PyErr_SetString(PyExc_ValueError,
                "expected elements of locations to be vectors of length 3");
            goto fail;
        }
    )
    INPUT_VECTOR_DOUBLE_NIFOS(horizons)
Beispiel #13
0
static PyObject* opnorm_opnorm(PyObject *self, PyObject *args, PyObject *kwargs)
{
    PyArrayObject *A;
    double p, q, eps = 1e-10;
    size_t fifomax = 0;
    static char *kwlist[] = {"A", "p", "q", "eps", "fifomax", NULL};

    /* get arguments */

    if (! PyArg_ParseTupleAndKeywords(args, kwargs, "Odd|dn", kwlist,
                                      &A, &p, &q, &eps, &fifomax) )
    {
        PyErr_SetString(PyExc_ValueError, "error parsing arguments");
        return NULL;
    }

    /* check and retrieve dimension */

    if (PyArray_NDIM(A) != 2)
    {
        PyErr_SetString(PyExc_ValueError, "First argument must be 2D array");
        return NULL;
    }

    size_t
    m = PyArray_DIM(A, 0),
    n = PyArray_DIM(A, 1);

    /* get matrix data */

    const double *Adat = PyArray_DATA(A);

    /* create array object for maximising vector */

    PyArrayObject *vmax;
    npy_intp dims[1] = {n};

    if (! (vmax = (PyArrayObject*)PyArray_SimpleNew(1, dims, NPY_DOUBLE)))
    {
        PyErr_SetString(PyExc_RuntimeError, "failed to create output array");
        return NULL;
    }

    /* get underlying data for vmax */

    double *vdat = (double*)PyArray_DATA(vmax);

    /* run opnorm */

    double N;
    opnorm_opt_t opt = { .eps = eps, .fifomax = fifomax };
    opnorm_stats_t stats;

    int err = opnorm(Adat, row_major, m, n, p, q, opt, &N, vdat, &stats);

    if (err)
    {
        const char *msg = opnorm_strerror(err);
        switch (err)
        {
        case OPNORM_EDOM_P:
        case OPNORM_EDOM_Q:
        case OPNORM_EDOM_EPS:
            PyErr_SetString(PyExc_ValueError, msg);
            break;
        default:
            PyErr_SetString(PyExc_RuntimeError, msg);
        }
        return NULL;
    }

    return Py_BuildValue("fO{s:k,s:k,s:k,s:I}", N, vmax,
                         "neval",   stats.neval,
                         "nfifo",   stats.nfifo,
                         "fifomax", stats.fifomax,
                         "nthread", stats.nthread);
}
Beispiel #14
0
PyObject *
save_png_fast_progressive (char *filename,
                           int w, int h,
                           bool has_alpha,
                           PyObject *data_generator,
                           bool write_legacy_png)
{
  png_structp png_ptr = NULL;
  png_infop info_ptr = NULL;
  PyObject * result = NULL;
  int bpc;
  FILE * fp = NULL;
  PyObject *iterator = NULL;

  /* TODO: try if this silliness helps
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
  png_uint_32 mask, flags;
  
  flags = png_get_asm_flags(png_ptr);
  mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
  png_set_asm_flags(png_ptr, flags | mask);
#endif
  */

  bpc = 8;
  
  fp = fopen(filename, "wb");
  if (!fp) {
    PyErr_SetFromErrno(PyExc_IOError);
    //PyErr_Format(PyExc_IOError, "Could not open PNG file for writing: %s", filename);
    goto cleanup;
  }

  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, png_write_error_callback, NULL);
  if (!png_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_write_struct() failed");
    goto cleanup;
  }

  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_info_struct() failed");
    goto cleanup;
  }

  if (setjmp(png_jmpbuf(png_ptr))) {
    goto cleanup;
  }

  png_init_io(png_ptr, fp);

  png_set_IHDR (png_ptr, info_ptr,
                w, h, bpc,
                has_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
                PNG_INTERLACE_NONE,
                PNG_COMPRESSION_TYPE_BASE,
                PNG_FILTER_TYPE_BASE);

  if (! write_legacy_png) {
    // Internal data is sRGB by the time it gets here.
    // Explicitly save with the recommended chunks to advertise that fact.
    png_set_sRGB_gAMA_and_cHRM (png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
  }

  // default (all filters enabled):                 1350ms, 3.4MB
  //png_set_filter(png_ptr, 0, PNG_FILTER_NONE);  // 790ms, 3.8MB
  //png_set_filter(png_ptr, 0, PNG_FILTER_PAETH); // 980ms, 3.5MB
  png_set_filter(png_ptr, 0, PNG_FILTER_SUB);     // 760ms, 3.4MB

  //png_set_compression_level(png_ptr, 0); // 0.49s, 32MB
  //png_set_compression_level(png_ptr, 1); // 0.98s, 9.6MB
  png_set_compression_level(png_ptr, 2);   // 1.08s, 9.4MB
  //png_set_compression_level(png_ptr, 9); // 18.6s, 9.3MB

  png_write_info(png_ptr, info_ptr);

  if (!has_alpha) {
    // input array format format is rgbu
    png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
  }

  {
    iterator = PyObject_GetIter(data_generator);
    if (!iterator) goto cleanup;

    int y = 0;
    while (y < h) {
      int rows;
      PyObject * arr = PyIter_Next(iterator);
      if (PyErr_Occurred()) goto cleanup;
      assert(arr); // iterator should have data
      assert(PyArray_ISALIGNED(arr));
      assert(PyArray_NDIM(arr) == 3);
      assert(PyArray_DIM(arr, 1) == w);
      assert(PyArray_DIM(arr, 2) == 4); // rgbu
      assert(PyArray_TYPE(arr) == NPY_UINT8);
      assert(PyArray_STRIDE(arr, 1) == 4);
      assert(PyArray_STRIDE(arr, 2) == 1);

      rows = PyArray_DIM(arr, 0);
      assert(rows > 0);
      y += rows;
      png_bytep p = (png_bytep)PyArray_DATA(arr);
      for (int row=0; row<rows; row++) {
        png_write_row (png_ptr, p);
        p += PyArray_STRIDE(arr, 0);
      }
      Py_DECREF(arr);
    }
    assert(y == h);
    PyObject * obj = PyIter_Next(iterator);
    assert(!obj); // iterator should be finished
    if (PyErr_Occurred()) goto cleanup;
  }

  png_write_end (png_ptr, NULL);

  result = Py_BuildValue("{}");

 cleanup:
  if (iterator) Py_DECREF(iterator);
  if (info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
  if (fp) fclose(fp);
  return result;
}
Beispiel #15
0
static PyObject *somap(PyObject *self, PyObject *args)
{
    int ninputs, nsteps, nrows, ncols, depth, width, height, i, j, k;
    PyArrayObject *inputs_obj, *spread_obj;
    PyObject *somap_obj;
    double **inputs, **spread, ***somap;
    time_t t0, t1;
    npy_intp dims[3];

    if (!PyArg_ParseTuple(args, "O!O!iii", &PyArray_Type, &inputs_obj, &PyArray_Type, &spread_obj, &nrows, &ncols, &nsteps))
	RETURN_ERROR("need five arguments: inputs, spread, nrows, ncols, nsteps");

    if (!PyArray_Check(inputs_obj))
	RETURN_ERROR("inputs needs to be NumPy array");

    if (PyArray_NDIM(inputs_obj) != 2)
	RETURN_ERROR("inputs needs to be NumPy array with ndim 2");

    if (!PyArray_Check(spread_obj))
	RETURN_ERROR("spread needs to be NumPy array");

    if (PyArray_NDIM(spread_obj) != 2)
	RETURN_ERROR("spread needs to be NumPy array with ndim 2");

    if (PyArray_TYPE(inputs_obj) != NPY_DOUBLE)
	RETURN_ERROR("inputs needs to be array of doubles");

    if (PyArray_TYPE(spread_obj) != NPY_DOUBLE)
	RETURN_ERROR("spread needs to be array of doubles");

    ninputs = PyArray_DIM(inputs_obj, 0);
    depth = PyArray_DIM(inputs_obj, 1);

    width = PyArray_DIM(spread_obj, 0);
    height = PyArray_DIM(spread_obj, 1);

    //if (PyArray_AsCArray((PyObject**) &inputs_obj, (void *) &inputs, PyArray_DIMS(inputs_obj), PyArray_NDIM(inputs_obj), PyArray_DescrFromType(NPY_DOUBLE)) < 0)
    if (!(inputs = copyArray2(inputs_obj)))
	RETURN_ERROR("getting inputs as C array");

    //if (PyArray_AsCArray((PyObject**) &spread_obj, (void *) &spread, PyArray_DIMS(spread_obj), PyArray_NDIM(spread_obj), PyArray_DescrFromType(NPY_DOUBLE)) < 0)
    if (!(spread = copyArray2(spread_obj)))
    {
    	//PyArray_Free((PyObject*) inputs_obj, (void *) inputs);
        freeArray2(inputs, ninputs);
	RETURN_ERROR("getting spread as C array");
    }

    t0 = time(NULL);

    somap = selfOrganisingMap(inputs, ninputs, depth, nrows, ncols, spread, width, height, nsteps);

    t1 = time(NULL);

    printf("Time for just somap = %ld\n", t1-t0);

    //somap_obj = PyArray_NewFromDescr(&PyArray_Type, PyArray_DescrFromType(NPY_DOUBLE), PyArray_NDIM(inputs_obj), PyArray_DIMS(inputs_obj), NULL, (void *) somap, 0, NULL);
    // below does not work because data not contiguous
    //somap_obj = PyArray_SimpleNewFromData(PyArray_NDIM(inputs_obj), PyArray_DIMS(inputs_obj), NPY_DOUBLE, (void *) somap);
    dims[0] = nrows;
    dims[1] = ncols;
    dims[2] = depth;
    somap_obj = PyArray_SimpleNew(3, dims, NPY_DOUBLE);
    for (i = 0; i < nrows; i++)
      for (j = 0; j < ncols; j++)
        for (k = 0; k < depth; k++)
          *((double *) PyArray_GETPTR3(somap_obj, i, j, k)) = somap[i][j][k];

    //PyArray_Free((PyObject*) inputs_obj, (void *) inputs);
    //PyArray_Free((PyObject*) spread_obj, (void *) spread);
    freeArray3(somap, nrows, ncols);
    freeArray2(inputs, ninputs);
    freeArray2(spread, width);

    return somap_obj;
}
Beispiel #16
0
static PyObject* gridder_3D(PyObject *self, PyObject *args, PyObject *kwargs){
  PyArrayObject *gridout = NULL, *grid2out = NULL, *Nout = NULL, *stderror = NULL;
  PyArrayObject *gridI = NULL;
  PyObject *_dout = NULL, *_d2out = NULL, *_nout = NULL;
  PyObject *_I;

  npy_intp data_size;
  npy_intp dims[3];

  double grid_start[3];
  double grid_stop[3];
  unsigned long grid_nsteps[3];

  int ignore_nan = 0; 

  int retval;

  static char *kwlist[] = { "data", "xrange", "yrange", "zrange", "ignore_nan", 
                            "gridout", "grid2out", "nout", NULL }; 

  if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O(ddd)(ddd)(lll)|dOOO", kwlist, 
				  &_I,
				  &grid_start[0], &grid_start[1], &grid_start[2],
				  &grid_stop[0], &grid_stop[1], &grid_stop[2],
				  &grid_nsteps[0], &grid_nsteps[1], &grid_nsteps[2],
          &ignore_nan, &_dout, &_d2out, &_nout)){
    return NULL;
  }

  gridI = (PyArrayObject*)PyArray_FROMANY(_I, NPY_DOUBLE, 0, 0, NPY_ARRAY_IN_ARRAY);
  if(!gridI){
    goto error;
  }

  data_size = PyArray_DIM(gridI, 0);
  if(PyArray_DIM(gridI, 1) != 4){
    PyErr_SetString(PyExc_ValueError, "Dimension 1 of array must be 4");
    goto error;
  }

  dims[0] = grid_nsteps[0];
  dims[1] = grid_nsteps[1];
  dims[2] = grid_nsteps[2];

  if(_dout == NULL){
    gridout = (PyArrayObject*)PyArray_ZEROS(3, dims, NPY_DOUBLE, 0);
  } else {
    gridout = (PyArrayObject*)PyArray_FROMANY(_dout, NPY_DOUBLE, 0, 0, NPY_ARRAY_IN_ARRAY);
  }
  if(!gridout){
    goto error;
  }

  if(_d2out == NULL){
    grid2out = (PyArrayObject*)PyArray_ZEROS(3, dims, NPY_DOUBLE, 0);
  } else {
    grid2out = (PyArrayObject*)PyArray_FROMANY(_d2out, NPY_DOUBLE, 0, 0, NPY_ARRAY_IN_ARRAY);
  }
  if(!grid2out){
    goto error;
  }

  if(_nout == NULL){
    Nout = (PyArrayObject*)PyArray_ZEROS(3, dims, NPY_ULONG, 0);
  } else {
    Nout = (PyArrayObject*)PyArray_FROMANY(_nout, NPY_ULONG, 0, 0, NPY_ARRAY_IN_ARRAY);
  }
  if(!Nout){
    goto error;
  }

  stderror = (PyArrayObject*)PyArray_SimpleNew(3, dims, NPY_DOUBLE);
  if(!stderror){
    goto error;
  }

  // Ok now we don't touch Python Object ... Release the GIL
  Py_BEGIN_ALLOW_THREADS

  retval = c_grid3d((double*)PyArray_DATA(gridout), (double *)PyArray_DATA(grid2out),
                    (unsigned long*)PyArray_DATA(Nout),
                    (double*)PyArray_DATA(stderror), (double*)PyArray_DATA(gridI),
		                grid_start, grid_stop, (unsigned long)data_size, grid_nsteps,
                    ignore_nan);

  // Ok now get the GIL back
  Py_END_ALLOW_THREADS

  if(retval){
    // We had a runtime error
    PyErr_SetString(PyExc_MemoryError, "Could not allocate memory in c_grid3d");
    goto error;
  }

  Py_XDECREF(gridI);
  return Py_BuildValue("NNNN", gridout, grid2out, Nout, stderror);

error:
  Py_XDECREF(gridI);
  Py_XDECREF(gridout);
  Py_XDECREF(grid2out);
  Py_XDECREF(Nout);
  Py_XDECREF(stderror);
  return NULL;
}
Beispiel #17
0
static PyObject *
PyUFunc_Accumulate(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
                   int axis, int otype)
{
    PyArrayObject *op[2];
    PyArray_Descr *op_dtypes[2] = {NULL, NULL};
    int op_axes_arrays[2][NPY_MAXDIMS];
    int *op_axes[2] = {op_axes_arrays[0], op_axes_arrays[1]};
    npy_uint32 op_flags[2];
    int idim, ndim, otype_final;
    int needs_api, need_outer_iterator;

    NpyIter *iter = NULL, *iter_inner = NULL;

    /* The selected inner loop */
    PyUFuncGenericFunction innerloop = NULL;
    void *innerloopdata = NULL;

    const char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";

    /* These parameters come from extobj= or from a TLS global */
    int buffersize = 0, errormask = 0;

    NPY_BEGIN_THREADS_DEF;

    NPY_UF_DBG_PRINT1("\nEvaluating ufunc %s.accumulate\n", ufunc_name);

#if 0
    printf("Doing %s.accumulate on array with dtype :  ", ufunc_name);
    PyObject_Print((PyObject *)PyArray_DESCR(arr), stdout, 0);
    printf("\n");
#endif

    if (_get_bufsize_errmask(NULL, "accumulate", &buffersize, &errormask) < 0) {
        return NULL;
    }

    /* Take a reference to out for later returning */
    Py_XINCREF(out);

    otype_final = otype;
    if (get_binary_op_function(ufunc, &otype_final,
                                &innerloop, &innerloopdata) < 0) {
        PyArray_Descr *dtype = PyArray_DescrFromType(otype);
        PyErr_Format(PyExc_ValueError,
                     "could not find a matching type for %s.accumulate, "
                     "requested type has type code '%c'",
                            ufunc_name, dtype ? dtype->type : '-');
        Py_XDECREF(dtype);
        goto fail;
    }

    ndim = PyArray_NDIM(arr);

    /*
     * Set up the output data type, using the input's exact
     * data type if the type number didn't change to preserve
     * metadata
     */
    if (PyArray_DESCR(arr)->type_num == otype_final) {
        if (PyArray_ISNBO(PyArray_DESCR(arr)->byteorder)) {
            op_dtypes[0] = PyArray_DESCR(arr);
            Py_INCREF(op_dtypes[0]);
        }
        else {
            op_dtypes[0] = PyArray_DescrNewByteorder(PyArray_DESCR(arr),
                                                    NPY_NATIVE);
        }
    }
    else {
        op_dtypes[0] = PyArray_DescrFromType(otype_final);
    }
    if (op_dtypes[0] == NULL) {
        goto fail;
    }

#if NPY_UF_DBG_TRACING
    printf("Found %s.accumulate inner loop with dtype :  ", ufunc_name);
    PyObject_Print((PyObject *)op_dtypes[0], stdout, 0);
    printf("\n");
#endif

    /* Set up the op_axes for the outer loop */
    for (idim = 0; idim < ndim; ++idim) {
        op_axes_arrays[0][idim] = idim;
        op_axes_arrays[1][idim] = idim;
    }

    /* The per-operand flags for the outer loop */
    op_flags[0] = NPY_ITER_READWRITE |
                  NPY_ITER_NO_BROADCAST |
                  NPY_ITER_ALLOCATE |
                  NPY_ITER_NO_SUBTYPE;
    op_flags[1] = NPY_ITER_READONLY;

    op[0] = out;
    op[1] = arr;

    need_outer_iterator = (ndim > 1);
    /* We can't buffer, so must do UPDATEIFCOPY */
    if (!PyArray_ISALIGNED(arr) || (out && !PyArray_ISALIGNED(out)) ||
            !PyArray_EquivTypes(op_dtypes[0], PyArray_DESCR(arr)) ||
            (out &&
             !PyArray_EquivTypes(op_dtypes[0], PyArray_DESCR(out)))) {
        need_outer_iterator = 1;
    }

    if (need_outer_iterator) {
        int ndim_iter = 0;
        npy_uint32 flags = NPY_ITER_ZEROSIZE_OK|
                           NPY_ITER_REFS_OK;
        PyArray_Descr **op_dtypes_param = NULL;

        /*
         * The way accumulate is set up, we can't do buffering,
         * so make a copy instead when necessary.
         */
        ndim_iter = ndim;
        flags |= NPY_ITER_MULTI_INDEX;
        /* Add some more flags */
        op_flags[0] |= NPY_ITER_UPDATEIFCOPY|NPY_ITER_ALIGNED;
        op_flags[1] |= NPY_ITER_COPY|NPY_ITER_ALIGNED;
        op_dtypes_param = op_dtypes;
        op_dtypes[1] = op_dtypes[0];
        NPY_UF_DBG_PRINT("Allocating outer iterator\n");
        iter = NpyIter_AdvancedNew(2, op, flags,
                                   NPY_KEEPORDER, NPY_UNSAFE_CASTING,
                                   op_flags,
                                   op_dtypes_param,
                                   ndim_iter, op_axes, NULL, 0);
        if (iter == NULL) {
            goto fail;
        }

        /* In case COPY or UPDATEIFCOPY occurred */
        op[0] = NpyIter_GetOperandArray(iter)[0];
        op[1] = NpyIter_GetOperandArray(iter)[1];

        if (PyArray_SIZE(op[0]) == 0) {
            if (out == NULL) {
                out = op[0];
                Py_INCREF(out);
            }
            goto finish;
        }

        if (NpyIter_RemoveAxis(iter, axis) != NPY_SUCCEED) {
            goto fail;
        }
        if (NpyIter_RemoveMultiIndex(iter) != NPY_SUCCEED) {
            goto fail;
        }
    }

    /* Get the output */
    if (out == NULL) {
        if (iter) {
            op[0] = out = NpyIter_GetOperandArray(iter)[0];
            Py_INCREF(out);
        }
        else {
            PyArray_Descr *dtype = op_dtypes[0];
            Py_INCREF(dtype);
            op[0] = out = (PyArrayObject *)PyArray_NewFromDescr(
                                    &PyArray_Type, dtype,
                                    ndim, PyArray_DIMS(op[1]), NULL, NULL,
                                    0, NULL);
            if (out == NULL) {
                goto fail;
            }

        }
    }

    /*
     * If the reduction axis has size zero, either return the reduction
     * unit for UFUNC_REDUCE, or return the zero-sized output array
     * for UFUNC_ACCUMULATE.
     */
    if (PyArray_DIM(op[1], axis) == 0) {
        goto finish;
    }
    else if (PyArray_SIZE(op[0]) == 0) {
        goto finish;
    }

    if (iter && NpyIter_GetIterSize(iter) != 0) {
        char *dataptr_copy[3];
        npy_intp stride_copy[3];
        npy_intp count_m1, stride0, stride1;

        NpyIter_IterNextFunc *iternext;
        char **dataptr;

        int itemsize = op_dtypes[0]->elsize;

        /* Get the variables needed for the loop */
        iternext = NpyIter_GetIterNext(iter, NULL);
        if (iternext == NULL) {
            goto fail;
        }
        dataptr = NpyIter_GetDataPtrArray(iter);


        /* Execute the loop with just the outer iterator */
        count_m1 = PyArray_DIM(op[1], axis)-1;
        stride0 = 0, stride1 = PyArray_STRIDE(op[1], axis);

        NPY_UF_DBG_PRINT("UFunc: Reduce loop with just outer iterator\n");

        stride0 = PyArray_STRIDE(op[0], axis);

        stride_copy[0] = stride0;
        stride_copy[1] = stride1;
        stride_copy[2] = stride0;

        needs_api = NpyIter_IterationNeedsAPI(iter);

        NPY_BEGIN_THREADS_NDITER(iter);

        do {
            dataptr_copy[0] = dataptr[0];
            dataptr_copy[1] = dataptr[1];
            dataptr_copy[2] = dataptr[0];

            /*
             * Copy the first element to start the reduction.
             *
             * Output (dataptr[0]) and input (dataptr[1]) may point to
             * the same memory, e.g. np.add.accumulate(a, out=a).
             */
            if (otype == NPY_OBJECT) {
                /*
                 * Incref before decref to avoid the possibility of the
                 * reference count being zero temporarily.
                 */
                Py_XINCREF(*(PyObject **)dataptr_copy[1]);
                Py_XDECREF(*(PyObject **)dataptr_copy[0]);
                *(PyObject **)dataptr_copy[0] =
                                    *(PyObject **)dataptr_copy[1];
            }
            else {
                memmove(dataptr_copy[0], dataptr_copy[1], itemsize);
            }

            if (count_m1 > 0) {
                /* Turn the two items into three for the inner loop */
                dataptr_copy[1] += stride1;
                dataptr_copy[2] += stride0;
                NPY_UF_DBG_PRINT1("iterator loop count %d\n",
                                                (int)count_m1);
                innerloop(dataptr_copy, &count_m1,
                            stride_copy, innerloopdata);
            }
        } while (iternext(iter));

        NPY_END_THREADS;
    }
    else if (iter == NULL) {
        char *dataptr_copy[3];
        npy_intp stride_copy[3];

        int itemsize = op_dtypes[0]->elsize;

        /* Execute the loop with no iterators */
        npy_intp count = PyArray_DIM(op[1], axis);
        npy_intp stride0 = 0, stride1 = PyArray_STRIDE(op[1], axis);

        NPY_UF_DBG_PRINT("UFunc: Reduce loop with no iterators\n");

        if (PyArray_NDIM(op[0]) != PyArray_NDIM(op[1]) ||
                !PyArray_CompareLists(PyArray_DIMS(op[0]),
                                      PyArray_DIMS(op[1]),
                                      PyArray_NDIM(op[0]))) {
            PyErr_SetString(PyExc_ValueError,
                    "provided out is the wrong size "
                    "for the reduction");
            goto fail;
        }
        stride0 = PyArray_STRIDE(op[0], axis);

        stride_copy[0] = stride0;
        stride_copy[1] = stride1;
        stride_copy[2] = stride0;

        /* Turn the two items into three for the inner loop */
        dataptr_copy[0] = PyArray_BYTES(op[0]);
        dataptr_copy[1] = PyArray_BYTES(op[1]);
        dataptr_copy[2] = PyArray_BYTES(op[0]);

        /*
         * Copy the first element to start the reduction.
         *
         * Output (dataptr[0]) and input (dataptr[1]) may point to the
         * same memory, e.g. np.add.accumulate(a, out=a).
         */
        if (otype == NPY_OBJECT) {
            /*
             * Incref before decref to avoid the possibility of the
             * reference count being zero temporarily.
             */
            Py_XINCREF(*(PyObject **)dataptr_copy[1]);
            Py_XDECREF(*(PyObject **)dataptr_copy[0]);
            *(PyObject **)dataptr_copy[0] =
                                *(PyObject **)dataptr_copy[1];
        }
        else {
            memmove(dataptr_copy[0], dataptr_copy[1], itemsize);
        }

        if (count > 1) {
            --count;
            dataptr_copy[1] += stride1;
            dataptr_copy[2] += stride0;

            NPY_UF_DBG_PRINT1("iterator loop count %d\n", (int)count);

            needs_api = PyDataType_REFCHK(op_dtypes[0]);

            if (!needs_api) {
                NPY_BEGIN_THREADS_THRESHOLDED(count);
            }

            innerloop(dataptr_copy, &count,
                        stride_copy, innerloopdata);

            NPY_END_THREADS;
        }
    }

finish:
    Py_XDECREF(op_dtypes[0]);
    NpyIter_Deallocate(iter);
    NpyIter_Deallocate(iter_inner);

    return (PyObject *)out;

fail:
    Py_XDECREF(out);
    Py_XDECREF(op_dtypes[0]);

    NpyIter_Deallocate(iter);
    NpyIter_Deallocate(iter_inner);

    return NULL;
}
Beispiel #18
0
/* Computation functions */
static PyObject* ccdToQ(PyObject *self, PyObject *args, PyObject *kwargs){
  PyArrayObject *angles = NULL;
  PyObject *_angles = NULL;
  PyArrayObject *ubinv = NULL;
  PyObject *_ubinv = NULL;
  PyArrayObject *qOut = NULL;
  CCD ccd;
  npy_intp dims[2];
  npy_intp nimages;
  int retval;

  int mode;

  double lambda;

  double *anglesp = NULL;
  double *qOutp = NULL;
  double *ubinvp = NULL;
  double *delgam = NULL;

  static char *kwlist[] = { "angles", "mode", "ccd_size", "ccd_pixsize",
			                      "ccd_cen", "dist", "wavelength",
			                      "UBinv", NULL };

  if(!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi(ii)(dd)(dd)ddO", kwlist,
				                          &_angles,
				                          &mode,
				                          &ccd.xSize, &ccd.ySize,
				                          &ccd.xPixSize, &ccd.yPixSize,
				                          &ccd.xCen, &ccd.yCen,
				                          &ccd.dist,
				                          &lambda,
				                          &_ubinv)){

    return NULL;
  }

  ccd.size = ccd.xSize * ccd.ySize;

  angles = (PyArrayObject*)PyArray_FROMANY(_angles, NPY_DOUBLE, 2, 2, NPY_ARRAY_IN_ARRAY);
  if(!angles){
    goto cleanup;
  }

  ubinv = (PyArrayObject*)PyArray_FROMANY(_ubinv, NPY_DOUBLE, 2, 2, NPY_ARRAY_IN_ARRAY);
  if(!ubinv){
    goto cleanup;
  }

  ubinvp = (double *)PyArray_DATA(ubinv);

  nimages = PyArray_DIM(angles, 0);

  dims[0] = nimages * ccd.size;
  dims[1] = 3;

  qOut = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_DOUBLE);
  if(!qOut){
    goto cleanup;
  }

  anglesp = (double *)PyArray_DATA(angles);
  qOutp = (double *)PyArray_DATA(qOut);

  // Now create the arrays for delta-gamma pairs
  delgam = (double*)malloc(nimages * ccd.size * sizeof(double) * 2);
  if(!delgam){
    goto cleanup;
  }

  // Ok now we don't touch Python Object ... Release the GIL
  Py_BEGIN_ALLOW_THREADS

  retval = processImages(delgam, anglesp, qOutp, lambda, mode, (unsigned long)nimages,
                         ubinvp, &ccd);

  // Now we have finished with the magic ... Obtain the GIL
  Py_END_ALLOW_THREADS

  if(retval){
    PyErr_SetString(PyExc_RuntimeError, "Error processing images");
    goto cleanup;
  }

  Py_XDECREF(ubinv);
  Py_XDECREF(angles);
  if(delgam) free(delgam);
  return Py_BuildValue("N", qOut);

 cleanup:
  Py_XDECREF(ubinv);
  Py_XDECREF(angles);
  Py_XDECREF(qOut);
  if(delgam) free(delgam);
  return NULL;
}
Beispiel #19
0
static PyObject* gridder_3D(PyObject *self, PyObject *args, PyObject *kwargs){
  PyObject *gridout = NULL, *Nout = NULL, *standarderror = NULL;
  PyObject *gridI = NULL;
  PyObject *_I;
  
  static char *kwlist[] = { "data", "xrange", "yrange", "zrange", "norm", NULL };
  
  npy_intp data_size;
  npy_intp dims[3];
  
  double grid_start[3];
  double grid_stop[3];
  int grid_nsteps[3];
  int norm_data = 0;
  
  unsigned long n_outside;
  
  if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O(ddd)(ddd)(iii)|i", kwlist,
				  &_I, 
				  &grid_start[0], &grid_start[1], &grid_start[2],
				  &grid_stop[0], &grid_stop[1], &grid_stop[2],
				  &grid_nsteps[0], &grid_nsteps[1], &grid_nsteps[2],
				  &norm_data)){
    return NULL;
  }	
  
  gridI = PyArray_FROMANY(_I, NPY_DOUBLE, 0, 0, NPY_IN_ARRAY);
  if(!gridI){
    goto cleanup;
  }
  
  data_size = PyArray_DIM(gridI, 0);
  
  dims[0] = grid_nsteps[0];
  dims[1] = grid_nsteps[1];
  dims[2] = grid_nsteps[2];

  gridout = PyArray_ZEROS(3, dims, NPY_DOUBLE, 0);
  if(!gridout){
    goto cleanup;
  }
  Nout = PyArray_ZEROS(3, dims, NPY_ULONG, 0);
  if(!Nout){
    goto cleanup;
  }
  standarderror = PyArray_ZEROS(3, dims, NPY_DOUBLE, 0);
  if(!standarderror){
    goto cleanup;
  }
  
  n_outside = c_grid3d(PyArray_DATA(gridout), PyArray_DATA(Nout), 
		       PyArray_DATA(standarderror), PyArray_DATA(gridI),
		       grid_start, grid_stop, data_size, grid_nsteps, norm_data);
  
  Py_XDECREF(gridI);
  return Py_BuildValue("NNNl", gridout, Nout, standarderror, n_outside); 
  
 cleanup:
  Py_XDECREF(gridI);
  Py_XDECREF(gridout);
  Py_XDECREF(Nout);
  Py_XDECREF(standarderror);
  return NULL;
}
static PyObject *csolve(PyObject* self, PyObject *args, PyObject *kwargs)
{
  /* Expects a function call
   *     sol = csolve((m,n,p),c,Gx,Gi,Gp,h,dims,Ax,Ai,Ap,b,verbose)
   * where
   *
   * the triple (m,n,p) corresponds to:
   *    `m`: the rows of G
   *    `n`: the cols of G and A, must agree with the length of c
   *    `p`: the rows of A
   * `c` is a Numpy array of doubles
   * "G" is a sparse matrix in column compressed storage. "Gx" are the values,
   * "Gi" are the rows, and "Gp" are the column pointers.
   * `Gx` is a Numpy array of doubles
   * `Gi` is a Numpy array of ints
   * `Gp` is a Numpy array of ints
   * `h` is a Numpy array
   * `dims` is a dictionary with
   *    `dims['l']` an integer specifying the dimension of positive orthant cone
   *    `dims['q']` an *list* specifying dimensions of second-order cones
   *
   * "A" is an optional sparse matrix in column compressed storage. "Ax" are 
   * the values, "Ai" are the rows, and "Ap" are the column pointers.
   * `Ax` is a Numpy array of doubles
   * `Ai` is a Numpy array of ints
   * `Ap` is a Numpy array of ints
   * `b` is an optional argument, which is a Numpy array of doubles
   * `verbose` is an optional bool signaling whether to print info
   *
   * This call will solve the problem
   *
   *    minimize     c'*x
   *    subject to   A*x = b
   *                 h - G*x \in K
   *
   * The code returns a Python dictionary with five keys, 'x', 'y', 'info', 's',
   * and 'z'. These correspond to the following:
   *
   * `x`: primal variables
   * `y`: dual variables for equality constraints
   * `s`: slacks for Gx + s <= h, s \in K
   * `z`: dual variables for inequality constraints s \in K
   * `info`: another dictionary with the following fields:
   *    exitflag: 0=OPTIMAL, 1=PRIMAL INFEASIBLE, 2=DUAL INFEASIBLE, -1=MAXIT REACHED
   *  infostring: gives information about the status of solution
   *       pcost: value of primal objective
   *       dcost: value of dual objective
   *        pres: primal residual on inequalities and equalities
   *        dres: dual residual
   *        pinf: primal infeasibility measure
   *        dinf: dual infeasibility measure
   *     pinfres: NaN
   *     dinfres: 3.9666e+15
   *         gap: duality gap
   *      relgap: relative duality gap
   *          r0: ???
   *      numerr: numerical error?
   *        iter: number of iterations
   *      timing: dictionary with timing information
   */

  /* data structures for arguments */
  //matrix *c, *h, *b = NULL;
  //spmatrix *G, *A = NULL;
  
  PyArrayObject *Gx, *Gi, *Gp, *c, *h;
  PyArrayObject *Ax = NULL;
  PyArrayObject *Ai = NULL;
  PyArrayObject *Ap = NULL;
  PyArrayObject *b = NULL;
  PyObject *dims, *verbose = NULL;
  idxint n;      // number or variables
  idxint m;      // number of conic variables
  idxint p = 0;  // number of equality constraints
  idxint ncones = 0; // number of cones
  idxint numConicVariables = 0;

  /* ECOS data structures */
  idxint l = 0;
  idxint *q = NULL;


  pfloat *Gpr = NULL;
  idxint *Gjc = NULL;
  idxint *Gir = NULL;

  pfloat *Apr = NULL;
  idxint *Ajc = NULL;
  idxint *Air = NULL;

  pfloat *cpr = NULL;
  pfloat *hpr = NULL;
  pfloat *bpr = NULL;

  pwork* mywork;

  idxint i;
  static char *kwlist[] = {"shape", "c", "Gx", "Gi", "Gp", "h", "dims", "Ax", "Ai", "Ap", "b", "verbose", NULL};
  // parse the arguments and ensure they are the correct type
#ifdef DLONG
  static char *argparse_string = "(lll)O!O!O!O!O!O!|O!O!O!O!O!";
#else
  static char *argparse_string = "(iii)O!O!O!O!O!O!|O!O!O!O!O!";
#endif
    
  if( !PyArg_ParseTupleAndKeywords(args, kwargs, argparse_string, kwlist,
      &m, &n, &p,
      &PyArray_Type, &c,
      &PyArray_Type, &Gx,
      &PyArray_Type, &Gi,
      &PyArray_Type, &Gp,
      &PyArray_Type, &h,
      &PyDict_Type, &dims,
      &PyArray_Type, &Ax,
      &PyArray_Type, &Ai,
      &PyArray_Type, &Ap,
      &PyArray_Type, &b,
      &PyBool_Type, &verbose)
    ) { return NULL; }
  
  if (m < 0) {
    PyErr_SetString(PyExc_ValueError, "m must be a positive integer");
    return NULL;
  }

  if (n < 0) {
    PyErr_SetString(PyExc_ValueError, "n must be a positive integer");
    return NULL;
  }
  
  if (p < 0) {
    PyErr_SetString(PyExc_ValueError, "p must be a positive integer");
    return NULL;
  }
  
  /* get the typenum for the primitive int and double types */
  int intType = getIntType();
  int doubleType = getDoubleType();

  /* set G */
  if( !PyArray_ISFLOAT(Gx) || PyArray_NDIM(Gx) != 1) {
    PyErr_SetString(PyExc_TypeError, "Gx must be a numpy array of floats");
    return NULL;
  }
  if( !PyArray_ISINTEGER(Gi) || PyArray_NDIM(Gi) != 1) {
    PyErr_SetString(PyExc_TypeError, "Gi must be a numpy array of ints");
    return NULL;
  }
  if( !PyArray_ISINTEGER(Gp) || PyArray_NDIM(Gp) != 1) {
    PyErr_SetString(PyExc_TypeError, "Gp must be a numpy array of ints");
    return NULL;
  }
  PyArrayObject *Gx_arr = getContiguous(Gx, doubleType);
  PyArrayObject *Gi_arr = getContiguous(Gi, intType);
  PyArrayObject *Gp_arr = getContiguous(Gp, intType);
  Gpr = (pfloat *) PyArray_DATA(Gx_arr);
  Gir = (idxint *) PyArray_DATA(Gi_arr);
  Gjc = (idxint *) PyArray_DATA(Gp_arr);

  /* set c */
  if (!PyArray_ISFLOAT(c) || PyArray_NDIM(c) != 1) {
      PyErr_SetString(PyExc_TypeError, "c must be a dense numpy array with one dimension");
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      return NULL;
  }
  
  if (PyArray_DIM(c,0) != n){
      PyErr_SetString(PyExc_ValueError, "c has incompatible dimension with G");
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      return NULL;
  }
  PyArrayObject *c_arr = getContiguous(c, doubleType);
  cpr = (pfloat *) PyArray_DATA(c_arr);

  /* set h */
  if (!PyArray_ISFLOAT(h) || PyArray_NDIM(h) != 1) {
      PyErr_SetString(PyExc_TypeError, "h must be a dense numpy array with one dimension");
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr);
      return NULL;
  }


  if (PyArray_DIM(h,0) != m){
      PyErr_SetString(PyExc_ValueError, "h has incompatible dimension with G");
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr);
      return NULL;
  }
  PyArrayObject *h_arr = getContiguous(h, doubleType);
  hpr = (pfloat *) PyArray_DATA(h_arr);

  /* get dims['l'] */
  PyObject *linearObj = PyDict_GetItemString(dims, "l");
  if(linearObj) {
    if(PyInt_Check(linearObj) && ((l = (idxint) PyInt_AsLong(linearObj)) >= 0)) {
        numConicVariables += l;
    } else {
      PyErr_SetString(PyExc_TypeError, "dims['l'] ought to be a nonnegative integer");
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr);
      return NULL;
    }
  }

  /* get dims['q'] */
  PyObject *socObj = PyDict_GetItemString(dims, "q");
  if(socObj) {
    if (PyList_Check(socObj)) {
      ncones = PyList_Size(socObj);
      q = calloc(ncones, sizeof(idxint));
      for (i = 0; i < ncones; ++i) {
          PyObject *qi = PyList_GetItem(socObj, i);
          if(PyInt_Check(qi) && ((q[i] = (idxint) PyInt_AsLong(qi)) > 0)) {
              numConicVariables += q[i];
          } else {
            PyErr_SetString(PyExc_TypeError, "dims['q'] ought to be a list of positive integers");
            Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
            Py_DECREF(c_arr); Py_DECREF(h_arr);
            return NULL;
          }

      }
    } else {
      PyErr_SetString(PyExc_TypeError, "dims['q'] ought to be a list");
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr);
      return NULL;
    }
  }

  PyArrayObject *Ax_arr = NULL;
  PyArrayObject *Ai_arr = NULL;
  PyArrayObject *Ap_arr = NULL;
  PyArrayObject *b_arr = NULL;
  if(Ax && Ai && Ap && b) {
    /* set A */
    if( !PyArray_ISFLOAT(Ax) || PyArray_NDIM(Ax) != 1 ) {
      PyErr_SetString(PyExc_TypeError, "Ax must be a numpy array of floats");
      if(q) free(q);
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr);
      return NULL;
    }
    if( !PyArray_ISINTEGER(Ai) || PyArray_NDIM(Ai) != 1) {
      PyErr_SetString(PyExc_TypeError, "Ai must be a numpy array of ints");
      if(q) free(q);
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr);
      return NULL;
    }
    if( !PyArray_ISINTEGER(Ap) || PyArray_NDIM(Ap) != 1) {
      PyErr_SetString(PyExc_TypeError, "Ap must be a numpy array of ints");
      if(q) free(q);
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr);
      return NULL;
    }
    // if ((SpMatrix_Check(A) && SP_ID(A) != DOUBLE)){
    //     PyErr_SetString(PyExc_TypeError, "A must be a sparse 'd' matrix");
    //     if(q) free(q);
    //     Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
    //     Py_DECREF(c_arr); Py_DECREF(h_arr);
    //     return NULL;
    // }
    // if ((p = SP_NROWS(A)) < 0) {
    //     PyErr_SetString(PyExc_ValueError, "p must be a nonnegative integer");
    //     if(q) free(q);
    //     Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
    //     Py_DECREF(c_arr); Py_DECREF(h_arr);
    //     return NULL;
    // }
    // if (SP_NCOLS(A) != n) {
    //     PyErr_SetString(PyExc_ValueError, "A has incompatible dimension with c");
    //     if(q) free(q);
    //     Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
    //     Py_DECREF(c_arr); Py_DECREF(h_arr);
    //     return NULL;
    // }
    // if (p != 0) {
    //   Apr = SP_VALD(A);
    //   Air = SP_ROW(A);
    //   Ajc = SP_COL(A);
    // }
    Ax_arr = getContiguous(Ax, doubleType);
    Ai_arr = getContiguous(Ai, intType);
    Ap_arr = getContiguous(Ap, intType);
    Apr = (pfloat *) PyArray_DATA(Ax_arr);
    Air = (idxint *) PyArray_DATA(Ai_arr);
    Ajc = (idxint *) PyArray_DATA(Ap_arr);

    /* set b */
    // if (!Matrix_Check(b) || MAT_NCOLS(b) != 1 || MAT_ID(b) != DOUBLE) {
    //     PyErr_SetString(PyExc_TypeError, "b must be a dense 'd' matrix with one column");
    //     if(q) free(q);
    //     return NULL;
    // }
    // if (MAT_NROWS(b) != p){
    //     PyErr_SetString(PyExc_ValueError, "b has incompatible dimension with A");
    //     if(q) free(q);
    //     return NULL;
    // }
    // if (p != 0) {
    //   bpr = MAT_BUFD(b);
    // }
    if (!PyArray_ISFLOAT(b) || PyArray_NDIM(b) != 1) {
        PyErr_SetString(PyExc_TypeError, "b must be a dense numpy array with one dimension");
        if(q) free(q);
        Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
        Py_DECREF(c_arr); Py_DECREF(h_arr);
        Py_DECREF(Ax_arr); Py_DECREF(Ai_arr); Py_DECREF(Ap_arr);
        return NULL;
    }
    if (PyArray_DIM(b,0) != p){
        PyErr_SetString(PyExc_ValueError, "b has incompatible dimension with A");
        if(q) free(q);
        Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
        Py_DECREF(c_arr); Py_DECREF(h_arr);
        Py_DECREF(Ax_arr); Py_DECREF(Ai_arr); Py_DECREF(Ap_arr);
        return NULL;
    }
    b_arr = getContiguous(b, doubleType);
    bpr = (pfloat *) PyArray_DATA(b_arr);
  } else if (Ax || Ai || Ap || b) {
    // check that A and b are both supplied
    PyErr_SetString(PyExc_ValueError, "A and b arguments must be supplied together");
    if(q) free(q);
    Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
    Py_DECREF(c_arr); Py_DECREF(h_arr);
    return NULL;
  }
  

  /* check that sum(q) + l = m */
  if( numConicVariables != m ){
      PyErr_SetString(PyExc_ValueError, "Number of rows of G does not match dims.l+sum(dims.q)");
      if (q) free(q);
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr); 
      if (b_arr) Py_DECREF(b_arr);
      if (Ax_arr) Py_DECREF(Ax_arr); 
      if (Ai_arr) Py_DECREF(Ai_arr); 
      if (Ap_arr) Py_DECREF(Ap_arr);
      return NULL;
  }
  
  /* This calls ECOS setup function. */
  mywork = ECOS_setup(n, m, p, l, ncones, q, Gpr, Gjc, Gir, Apr, Ajc, Air, cpr, hpr, bpr);
  if( mywork == NULL ){
      PyErr_SetString(PyExc_RuntimeError, "Internal problem occurred in ECOS while setting up the problem.\nPlease send a bug report with data to Alexander Domahidi.\nEmail: [email protected]");
      if(q) free(q);
      Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
      Py_DECREF(c_arr); Py_DECREF(h_arr);
      if (b_arr) Py_DECREF(b_arr);
      if (Ax_arr) Py_DECREF(Ax_arr); 
      if (Ai_arr) Py_DECREF(Ai_arr); 
      if (Ap_arr) Py_DECREF(Ap_arr);
      return NULL;
  }
  
  /* Set settings for ECOS. */
  if(verbose) {
    mywork->stgs->verbose = (idxint) PyObject_IsTrue(verbose);
  }
  
  /* Solve! */
  idxint exitcode = ECOS_solve(mywork);

  /* create output (all data is *deep copied*) */
  // TODO: request CVXOPT API for constructing from existing pointer
  /* x */
  // matrix *x;
  // if(!(x = Matrix_New(n,1,DOUBLE)))
  //   return PyErr_NoMemory();
  // memcpy(MAT_BUFD(x), mywork->x, n*sizeof(double));
  npy_intp veclen[1];
  veclen[0] = n;
  PyObject *x = PyArray_SimpleNewFromData(1, veclen, NPY_DOUBLE, mywork->x);

  /* y */
  // matrix *y;
  // if(!(y = Matrix_New(p,1,DOUBLE)))
  //   return PyErr_NoMemory();
  // memcpy(MAT_BUFD(y), mywork->y, p*sizeof(double));
  veclen[0] = p;
  PyObject *y = PyArray_SimpleNewFromData(1, veclen, NPY_DOUBLE, mywork->y);
  
  
  /* info dict */
  // infostring
  const char* infostring;
  switch( exitcode ){
      case ECOS_OPTIMAL:
          infostring = "Optimal solution found";
          break;
      case ECOS_MAXIT:
          infostring = "Maximum number of iterations reached";
          break;
      case ECOS_PINF:
          infostring = "Primal infeasible";
          break;
      case ECOS_DINF:
          infostring = "Dual infeasible";
          break;
      case ECOS_NUMERICS:
          infostring = "Run into numerical problems";
          break;
      case ECOS_OUTCONE:
          infostring = "PROBLEM: Multipliers leaving the cone";
          break;
      default:
          infostring = "UNKNOWN PROBLEM IN SOLVER";
  }

  // numerical errors
  idxint numerr = 0;
  if( (exitcode == ECOS_NUMERICS) || (exitcode == ECOS_OUTCONE) || (exitcode == ECOS_FATAL) ){
      numerr = 1;
  }

  // timings
#if PROFILING > 0
	PyObject *tinfos = Py_BuildValue(
#if PROFILING > 1
    "{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}",
#else
    "{s:d,s:d,s:d}",
#endif
#if PROFILING > 1
    "tkktcreate",(double)mywork->info->tkktcreate,
    "tkktsolve",(double)mywork->info->tkktsolve,
    "tkktfactor",(double)mywork->info->tfactor,
    "torder",(double)mywork->info->torder,
    "ttranspose",(double)mywork->info->ttranspose,
#endif
    "runtime",(double)mywork->info->tsolve + (double)mywork->info->tsetup,
    "tsetup",(double)mywork->info->tsetup,
    "tsolve",(double)mywork->info->tsolve);
#endif

  PyObject *infoDict = Py_BuildValue(
#if PROFILING > 0
    "{s:l,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:l,s:s,s:O,s:l}",
#else
    "{s:l,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:l,s:s,s:l}",
#endif
    "exitFlag", exitcode,
    "pcost", (double)mywork->info->pcost,
    "dcost", (double)mywork->info->dcost,
    "pres", (double)mywork->info->pres,
    "dres", (double)mywork->info->dres,
    "pinf", (double)mywork->info->pinf,
    "dinf", (double)mywork->info->dinf,
    "pinfres",(double)mywork->info->pinfres,
    "dinfres",(double)mywork->info->dinfres,
    "gap",(double)mywork->info->gap,
    "relgap",(double)mywork->info->relgap,
    "r0",(double)mywork->stgs->feastol,
    "iter",mywork->info->iter,
    "infostring",infostring,
#if PROFILING > 0
    "timing", tinfos,
#endif
    "numerr",numerr);

#if PROFILING > 0
  // give reference to infoDict
  Py_DECREF(tinfos);
#endif

  /* s */
  // matrix *s;
  // if(!(s = Matrix_New(m,1,DOUBLE)))
  //   return PyErr_NoMemory();
  // memcpy(MAT_BUFD(s), mywork->s, m*sizeof(double));
  veclen[0] = m;
  PyObject *s = PyArray_SimpleNewFromData(1, veclen, NPY_DOUBLE, mywork->s);
  
  /* z */
  // matrix *z;
  // if(!(z = Matrix_New(m,1,DOUBLE)))
  //   return PyErr_NoMemory();
  // memcpy(MAT_BUFD(z), mywork->z, m*sizeof(double));
  veclen[0] = m;
  PyObject *z = PyArray_SimpleNewFromData(1, veclen, NPY_DOUBLE, mywork->z);
  


  /* cleanup */
  ECOS_cleanup(mywork, 4);

  PyObject *returnDict = Py_BuildValue(
    "{s:O,s:O,s:O,s:O,s:O}",
    "x",x,
    "y",y,
    "z",z,
    "s",s,
    "info",infoDict);
  // give up ownership to the return dictionary
  Py_DECREF(x); Py_DECREF(y); Py_DECREF(z); Py_DECREF(s); Py_DECREF(infoDict);
  
  // no longer need pointers to arrays that held primitives
  if(q) free(q);
  Py_DECREF(Gx_arr); Py_DECREF(Gi_arr); Py_DECREF(Gp_arr);
  Py_DECREF(c_arr); Py_DECREF(h_arr);
  if (b_arr) Py_DECREF(b_arr);
  if (Ax_arr) Py_DECREF(Ax_arr); 
  if (Ai_arr) Py_DECREF(Ai_arr); 
  if (Ap_arr) Py_DECREF(Ap_arr);

  return returnDict;
}
static PyObject *Py_is_sorted(PyObject *self, PyObject *obj)
{
    npy_intp size;
    bool result;

    PyArrayObject *array = (PyArrayObject *)PyArray_FromAny(
        obj, NULL, 1, 1, 0, NULL);

    if (array == NULL) {
        return NULL;
    }

    size = PyArray_DIM(array, 0);

    if (size < 2) {
        Py_DECREF(array);
        Py_RETURN_TRUE;
    }

    /* Handle just the most common types here, otherwise coerce to
    double */
    switch(PyArray_TYPE(array)) {
    case NPY_INT:
        {
            _is_sorted_int<npy_int> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_LONG:
        {
            _is_sorted_int<npy_long> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_LONGLONG:
        {
            _is_sorted_int<npy_longlong> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_FLOAT:
        {
            _is_sorted<npy_float> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_DOUBLE:
        {
            _is_sorted<npy_double> is_sorted;
            result = is_sorted(array);
        }
        break;

    default:
        {
            Py_DECREF(array);
            array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1);

            if (array == NULL) {
                return NULL;
            }

            _is_sorted<npy_double> is_sorted;
            result = is_sorted(array);
        }
    }

    Py_DECREF(array);

    if (result) {
        Py_RETURN_TRUE;
    } else {
        Py_RETURN_FALSE;
    }
}
Beispiel #22
0
/* one-dimensional spline filter: */
int NI_SplineFilter1D(PyArrayObject *input, int order, int axis,
                                            PyArrayObject *output)
{
    int hh, npoles = 0, more;
    npy_intp kk, ll, lines, len;
    double *buffer = NULL, weight, pole[2];
    NI_LineBuffer iline_buffer, oline_buffer;
    NPY_BEGIN_THREADS_DEF;

    len = PyArray_NDIM(input) > 0 ? PyArray_DIM(input, axis) : 1;
    if (len < 1)
        goto exit;

    /* these are used in the spline filter calculation below: */
    switch (order) {
    case 2:
        npoles = 1;
        pole[0] = sqrt(8.0) - 3.0;
        break;
    case 3:
        npoles = 1;
        pole[0] = sqrt(3.0) - 2.0;
        break;
    case 4:
        npoles = 2;
        pole[0] = sqrt(664.0 - sqrt(438976.0)) + sqrt(304.0) - 19.0;
        pole[1] = sqrt(664.0 + sqrt(438976.0)) - sqrt(304.0) - 19.0;
        break;
    case 5:
        npoles = 2;
        pole[0] = sqrt(67.5 - sqrt(4436.25)) + sqrt(26.25) - 6.5;
        pole[1] = sqrt(67.5 + sqrt(4436.25)) - sqrt(26.25) - 6.5;
        break;
    default:
        break;
    }

    weight = 1.0;
    for(hh = 0; hh < npoles; hh++)
        weight *= (1.0 - pole[hh]) * (1.0 - 1.0 / pole[hh]);

    /* allocate an initialize the line buffer, only a single one is used,
         because the calculation is in-place: */
    lines = -1;
    if (!NI_AllocateLineBuffer(input, axis, 0, 0, &lines, BUFFER_SIZE,
                                                         &buffer))
        goto exit;
    if (!NI_InitLineBuffer(input, axis, 0, 0, lines, buffer,
                                                 NI_EXTEND_DEFAULT, 0.0, &iline_buffer))
        goto exit;
    if (!NI_InitLineBuffer(output, axis, 0, 0, lines, buffer,
                                                 NI_EXTEND_DEFAULT, 0.0, &oline_buffer))
        goto exit;

    NPY_BEGIN_THREADS;

    /* iterate over all the array lines: */
    do {
        /* copy lines from array to buffer: */
        if (!NI_ArrayToLineBuffer(&iline_buffer, &lines, &more)) {
            goto exit;
        }
        /* iterate over the lines in the buffer: */
        for(kk = 0; kk < lines; kk++) {
            /* get line: */
            double *ln = NI_GET_LINE(iline_buffer, kk);
            /* spline filter: */
            if (len > 1) {
                for(ll = 0; ll < len; ll++)
                    ln[ll] *= weight;
                for(hh = 0; hh < npoles; hh++) {
                    double p = pole[hh];
                    int max = (int)ceil(log(TOLERANCE) / log(fabs(p)));
                    if (max < len) {
                        double zn = p;
                        double sum = ln[0];
                        for(ll = 1; ll < max; ll++) {
                            sum += zn * ln[ll];
                            zn *= p;
                        }
                        ln[0] = sum;
                    } else {
                        double zn = p;
                        double iz = 1.0 / p;
                        double z2n = pow(p, (double)(len - 1));
                        double sum = ln[0] + z2n * ln[len - 1];
                        z2n *= z2n * iz;
                        for(ll = 1; ll <= len - 2; ll++) {
                            sum += (zn + z2n) * ln[ll];
                            zn *= p;
                            z2n *= iz;
                        }
                        ln[0] = sum / (1.0 - zn * zn);
                    }
                    for(ll = 1; ll < len; ll++)
                        ln[ll] += p * ln[ll - 1];
                    ln[len-1] = (p / (p * p - 1.0)) * (ln[len-1] + p * ln[len-2]);
                    for(ll = len - 2; ll >= 0; ll--)
                        ln[ll] = p * (ln[ll + 1] - ln[ll]);
                }
            }
        }
        /* copy lines from buffer to array: */
        if (!NI_LineBufferToArray(&oline_buffer)) {
            goto exit;
        }
    } while(more);

 exit:
    NPY_END_THREADS;
    free(buffer);
    return PyErr_Occurred() ? 0 : 1;
}
Beispiel #23
0
PyObject *
py_angle_distribution(PyObject *self, PyObject *args)
{
  PyObject *i_arr, *j_arr, *r_arr;
  int nbins;
  double cutoff;

  if (!PyArg_ParseTuple(args, "O!O!O!id", &PyArray_Type, &i_arr, &PyArray_Type,
                        &j_arr, &PyArray_Type, &r_arr, &nbins, &cutoff))
    return NULL;

  if (PyArray_NDIM(i_arr) != 1 || PyArray_TYPE(i_arr) != NPY_INT) {
    PyErr_SetString(PyExc_TypeError, "First argument needs to be one-dimensional "
                    "integer array.");
    return NULL;
  }
  if (PyArray_NDIM(j_arr) != 1 || PyArray_TYPE(j_arr) != NPY_INT) {
    PyErr_SetString(PyExc_TypeError, "Second argument needs to be one-dimensional "
                    "integer array.");
    return NULL;
  }
  if (PyArray_NDIM(r_arr) != 2 || PyArray_DIM(r_arr, 1) != 3 ||
      PyArray_TYPE(r_arr) != NPY_DOUBLE) {
    PyErr_SetString(PyExc_TypeError, "Second argument needs to be two-dimensional "
                    "double array.");
    return NULL;
  }

  npy_intp npairs = PyArray_DIM(i_arr, 0);
  if (PyArray_DIM(j_arr, 0) != npairs || PyArray_DIM(r_arr, 0) != npairs) {
    PyErr_SetString(PyExc_RuntimeError, "First three arguments need to be arrays of "
                    "identical length.");
    return NULL;
  }

  npy_intp dim = nbins;
  PyObject *h_arr = PyArray_ZEROS(1, &dim, NPY_DOUBLE, 1);
  PyObject *h2_arr = PyArray_ZEROS(1, &dim, NPY_DOUBLE, 1);
  PyObject *tmp_arr = PyArray_ZEROS(1, &dim, NPY_INT, 1);

  npy_int *i = PyArray_DATA(i_arr);
  npy_int *j = PyArray_DATA(j_arr);
  double *r = PyArray_DATA(r_arr);
  double *h = PyArray_DATA(h_arr);
  double *h2 = PyArray_DATA(h2_arr);
  npy_int *tmp = PyArray_DATA(tmp_arr);

  npy_int last_i = i[0], i_start = 0;
  memset(tmp, 0, nbins*sizeof(npy_int));
  int nangle = 1, p;
  double cutoff_sq = cutoff*cutoff;
  for (p = 0; p < npairs; p++) {
    if (last_i != i[p]) {
      int bin;
      for (bin = 0; bin < nbins; bin++) {
        h[bin] += tmp[bin];
        h2[bin] += tmp[bin]*tmp[bin];
      }
      memset(tmp, 0, nbins*sizeof(npy_int));
      last_i = i[p];
      i_start = p;
    }

    double n = r[3*p]*r[3*p] + r[3*p+1]*r[3*p+1] + r[3*p+2]*r[3*p+2];

    if (n < cutoff_sq) {
      int p2;
      for (p2 = i_start; i[p2] == last_i; p2++) {
        if (p2 != p) {
          double n2 = r[3*p2]*r[3*p2] + r[3*p2+1]*r[3*p2+1] + r[3*p2+2]*r[3*p2+2];
          if (n2 < cutoff_sq) {
            double angle = r[3*p]*r[3*p2] + r[3*p+1]*r[3*p2+1] + r[3*p+2]*r[3*p2+2];
            angle = acos(angle/sqrt(n*n2));
            int bin = (int) (nbins*angle/M_PI);
            while (bin < 0)  bin += nbins;
            while (bin >= nbins)  bin -= nbins;
            tmp[bin]++;
            nangle++;
          } /* n2 < cutoff_sq */
        } /* p!= p */
      }
    } /* n < cutoff_sq */
  }
  double binvol = M_PI/nbins;
  int bin;
  for (bin = 0; bin < nbins; bin++) {
    h[bin] += tmp[bin];
    h2[bin] += tmp[bin]*tmp[bin];

    h[bin] /= nangle*binvol;
    h2[bin] /= nangle*binvol*binvol;
    h2[bin] -= h[bin]*h[bin];
  }

  Py_DECREF(tmp_arr);

  return Py_BuildValue("OO", h_arr, h2_arr);
}
Beispiel #24
0
int
NI_GeometricTransform(PyArrayObject *input, int (*map)(npy_intp*, double*,
                int, int, void*), void* map_data, PyArrayObject* matrix_ar,
                PyArrayObject* shift_ar, PyArrayObject *coordinates,
                PyArrayObject *output, int order, int mode, double cval)
{
    char *po, *pi, *pc = NULL;
    npy_intp **edge_offsets = NULL, **data_offsets = NULL, filter_size;
    npy_intp ftmp[NPY_MAXDIMS], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp cstride = 0, kk, hh, ll, jj;
    npy_intp size;
    double **splvals = NULL, icoor[NPY_MAXDIMS];
    npy_intp idimensions[NPY_MAXDIMS], istrides[NPY_MAXDIMS];
    NI_Iterator io, ic;
    npy_double *matrix = matrix_ar ? (npy_double*)PyArray_DATA(matrix_ar) : NULL;
    npy_double *shift = shift_ar ? (npy_double*)PyArray_DATA(shift_ar) : NULL;
    int irank = 0, orank;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    for(kk = 0; kk < PyArray_NDIM(input); kk++) {
        idimensions[kk] = PyArray_DIM(input, kk);
        istrides[kk] = PyArray_STRIDE(input, kk);
    }
    irank = PyArray_NDIM(input);
    orank = PyArray_NDIM(output);

    /* if the mapping is from array coordinates: */
    if (coordinates) {
        /* initialize a line iterator along the first axis: */
        if (!NI_InitPointIterator(coordinates, &ic))
            goto exit;
        cstride = ic.strides[0];
        if (!NI_LineIterator(&ic, 0))
            goto exit;
        pc = (void *)(PyArray_DATA(coordinates));
    }

    /* offsets used at the borders: */
    edge_offsets = malloc(irank * sizeof(npy_intp*));
    data_offsets = malloc(irank * sizeof(npy_intp*));
    if (NPY_UNLIKELY(!edge_offsets || !data_offsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        data_offsets[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        data_offsets[jj] = malloc((order + 1) * sizeof(npy_intp));
        if (NPY_UNLIKELY(!data_offsets[jj])) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
    }
    /* will hold the spline coefficients: */
    splvals = malloc(irank * sizeof(double*));
    if (NPY_UNLIKELY(!splvals)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        splvals[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        splvals[jj] = malloc((order + 1) * sizeof(double));
        if (NPY_UNLIKELY(!splvals[jj])) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
    }

    filter_size = 1;
    for(jj = 0; jj < irank; jj++)
        filter_size *= order + 1;

    /* initialize output iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    /* get data pointers: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* make a table of all possible coordinates within the spline filter: */
    fcoordinates = malloc(irank * filter_size * sizeof(npy_intp));
    /* make a table of all offsets within the spline filter: */
    foffsets = malloc(filter_size * sizeof(npy_intp));
    if (NPY_UNLIKELY(!fcoordinates || !foffsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < irank; jj++)
            fcoordinates[jj + hh * irank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = irank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }

    size = PyArray_SIZE(output);
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        int constant = 0, edge = 0;
        npy_intp offset = 0;
        if (map) {
            NPY_END_THREADS;
            /* call mappint functions: */
            if (!map(io.coordinates, icoor, orank, irank, map_data)) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "unknown error in mapping function");
                goto exit;
            }
            NPY_BEGIN_THREADS;
        } else if (matrix) {
            /* do an affine transformation: */
            npy_double *p = matrix;
            for(hh = 0; hh < irank; hh++) {
                icoor[hh] = 0.0;
                for(ll = 0; ll < orank; ll++)
                    icoor[hh] += io.coordinates[ll] * *p++;
                icoor[hh] += shift[hh];
            }
        } else if (coordinates) {
            /* mapping is from an coordinates array: */
            char *p = pc;
            switch (PyArray_TYPE(coordinates)) {
                CASE_MAP_COORDINATES(NPY_BOOL, npy_bool,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_UBYTE, npy_ubyte,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_USHORT, npy_ushort,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_UINT, npy_uint,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_ULONG, npy_ulong,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_ULONGLONG, npy_ulonglong,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_BYTE, npy_byte,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_SHORT, npy_short,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_INT, npy_int,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_LONG, npy_long,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_LONGLONG, npy_longlong,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_FLOAT, npy_float,
                                     p, icoor, irank, cstride);
                CASE_MAP_COORDINATES(NPY_DOUBLE, npy_double,
                                     p, icoor, irank, cstride);
            default:
                NPY_END_THREADS;
                PyErr_SetString(PyExc_RuntimeError,
                                "coordinate array data type not supported");
                goto exit;
            }
        }
        /* iterate over axes: */
        for(hh = 0; hh < irank; hh++) {
            /* if the input coordinate is outside the borders, map it: */
            double cc = map_coordinate(icoor[hh], idimensions[hh], mode);
            if (cc > -1.0) {
                /* find the filter location along this axis: */
                npy_intp start;
                if (order & 1) {
                    start = (npy_intp)floor(cc) - order / 2;
                } else {
                    start = (npy_intp)floor(cc + 0.5) - order / 2;
                }
                /* get the offset to the start of the filter: */
                offset += istrides[hh] * start;
                if (start < 0 || start + order >= idimensions[hh]) {
                    /* implement border mapping, if outside border: */
                    edge = 1;
                    edge_offsets[hh] = data_offsets[hh];
                    for(ll = 0; ll <= order; ll++) {
                        npy_intp idx = start + ll;
                        npy_intp len = idimensions[hh];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            npy_intp s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (int)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (int)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        /* calculate and store the offests at this edge: */
                        edge_offsets[hh][ll] = istrides[hh] * (idx - start);
                    }
                } else {
                    /* we are not at the border, use precalculated offsets: */
                    edge_offsets[hh] = NULL;
                }
                spline_coefficients(cc, order, splvals[hh]);
            } else {
                /* we use the constant border condition: */
                constant = 1;
                break;
            }
        }

        if (!constant) {
            npy_intp *ff = fcoordinates;
            const int type_num = PyArray_TYPE(input);
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                double coeff = 0.0;
                npy_intp idx = 0;

                if (NPY_UNLIKELY(edge)) {
                    for(ll = 0; ll < irank; ll++) {
                        if (edge_offsets[ll])
                            idx += edge_offsets[ll][ff[ll]];
                        else
                            idx += ff[ll] * istrides[ll];
                    }
                } else {
                    idx = foffsets[hh];
                }
                idx += offset;
                switch (type_num) {
                    CASE_INTERP_COEFF(NPY_BOOL, npy_bool,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UBYTE, npy_ubyte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_USHORT, npy_ushort,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UINT, npy_uint,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONG, npy_ulong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONGLONG, npy_ulonglong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_BYTE, npy_byte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_SHORT, npy_short,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_INT, npy_int,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONG, npy_long,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONGLONG, npy_longlong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_FLOAT, npy_float,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_DOUBLE, npy_double,
                                      coeff, pi, idx);
                default:
                    NPY_END_THREADS;
                    PyErr_SetString(PyExc_RuntimeError,
                                    "data type not supported");
                    goto exit;
                }
                /* calculate the interpolated value: */
                for(ll = 0; ll < irank; ll++)
                    if (order > 0)
                        coeff *= splvals[ll][ff[ll]];
                t += coeff;
                ff += irank;
            }
        } else {
            t = cval;
        }
        /* store output value: */
        switch (PyArray_TYPE(output)) {
            CASE_INTERP_OUT(NPY_BOOL, npy_bool, po, t);
            CASE_INTERP_OUT_UINT(UBYTE, npy_ubyte, po, t);
            CASE_INTERP_OUT_UINT(USHORT, npy_ushort, po, t);
            CASE_INTERP_OUT_UINT(UINT, npy_uint, po, t);
            CASE_INTERP_OUT_UINT(ULONG, npy_ulong, po, t);
            CASE_INTERP_OUT_UINT(ULONGLONG, npy_ulonglong, po, t);
            CASE_INTERP_OUT_INT(BYTE, npy_byte, po, t);
            CASE_INTERP_OUT_INT(SHORT, npy_short, po, t);
            CASE_INTERP_OUT_INT(INT, npy_int, po, t);
            CASE_INTERP_OUT_INT(LONG, npy_long, po, t);
            CASE_INTERP_OUT_INT(LONGLONG, npy_longlong, po, t);
            CASE_INTERP_OUT(NPY_FLOAT, npy_float, po, t);
            CASE_INTERP_OUT(NPY_DOUBLE, npy_double, po, t);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        if (coordinates) {
            NI_ITERATOR_NEXT2(io, ic, po, pc);
        } else {
            NI_ITERATOR_NEXT(io, po);
        }
    }

 exit:
    NPY_END_THREADS;
    free(edge_offsets);
    if (data_offsets) {
        for(jj = 0; jj < irank; jj++)
            free(data_offsets[jj]);
        free(data_offsets);
    }
    if (splvals) {
        for(jj = 0; jj < irank; jj++)
            free(splvals[jj]);
        free(splvals);
    }
    free(foffsets);
    free(fcoordinates);
    return PyErr_Occurred() ? 0 : 1;
}
Beispiel #25
0
static PyObject *dtw_dtw(PyObject *self, PyObject *args, PyObject *keywds)
{
  PyObject *x  = NULL; PyObject *x_a  = NULL;
  PyObject *y  = NULL; PyObject *y_a  = NULL; 
  PyObject *startbc = Py_True;
  PyObject *onlydist = Py_False;
  int steppattern = 0;
  double r = 0.0;
  int wincond = 0;
 
  int *pathx, *pathy;
  int k;
  int sbc;
  double distance;
  int ** constr;

  npy_intp n, m;
  double *x_v, *y_v;
  
  PyObject *px_a    = NULL;
  PyObject *py_a    = NULL; 
  PyObject *dtwm_a  = NULL; 
  
  npy_intp p_dims[1];
  npy_intp dtwm_dims[2];

  int *px_v, *py_v;
  double *dtwm_v;

  int i;
 

  /* Parse Tuple*/
  static char *kwlist[] = {"x", "y", "startbc", "steppattern", "onlydist", "wincond", "r", NULL};
  if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|OiOid", kwlist,
				   &x, &y, &startbc, &steppattern, &onlydist, &wincond, &r))
    return NULL;

  x_a = PyArray_FROM_OTF(x, NPY_DOUBLE, NPY_IN_ARRAY);
  if (x_a == NULL) return NULL;
 
  y_a = PyArray_FROM_OTF(y, NPY_DOUBLE, NPY_IN_ARRAY);
  if (y_a == NULL) return NULL;

  if (PyArray_NDIM(x_a) != 1){
    PyErr_SetString(PyExc_ValueError, "x should be 1D numpy array or list");
    return NULL;
  }
  
  if (PyArray_NDIM(y_a) != 1){
    PyErr_SetString(PyExc_ValueError, "y should be 1D numpy array or list");
    return NULL;
  }

  x_v = (double *) PyArray_DATA(x_a);
  y_v = (double *) PyArray_DATA(y_a);
  n = (int) PyArray_DIM(x_a, 0);
  m = (int) PyArray_DIM(y_a, 0);

  
  switch (wincond)
    {
    case NOWINDOW:
      constr = no_window(n, m);
      break;
      
    case SAKOECHIBA:
      constr = sakoe_chiba(n, m, r);
      break;
      
    default:
      PyErr_SetString(PyExc_ValueError, "wincond is not valid");
      return NULL;
    }
  

  if (onlydist == Py_True)
    {
      switch (steppattern)
	{
	case SYMMETRIC0:
	  distance = symmetric0_od(x_v, y_v, n, m, constr);
	  break;
	  
	case QUASISYMMETRIC0:
	  distance = quasisymmetric0_od(x_v, y_v, n, m, constr);
	  break;
	  
	case ASYMMETRIC0:
	  distance = asymmetric0_od(x_v, y_v, n, m, constr);
	  break;
	  
	default:
	  PyErr_SetString(PyExc_ValueError, "steppattern is not valid");
	  return NULL;
	}

      free(constr[0]);
      free(constr[1]);
      free(constr);          
    
      Py_DECREF(x_a);
      Py_DECREF(y_a);
     
      return Py_BuildValue("d", distance);
    }
  else
    {
      dtwm_dims[0] = (npy_intp) n;
      dtwm_dims[1] = (npy_intp) m;
      dtwm_a = PyArray_SimpleNew(2, dtwm_dims, NPY_DOUBLE);
      dtwm_v = (double *) PyArray_DATA(dtwm_a);

      switch (steppattern)
	{
	case SYMMETRIC0:
	  distance = symmetric0(x_v, y_v, n, m, dtwm_v, constr);
	  break;
	  
	case QUASISYMMETRIC0:
	  distance = quasisymmetric0(x_v, y_v, n, m, dtwm_v, constr);
	  break;
	  
	case ASYMMETRIC0:
	  distance = asymmetric0(x_v, y_v, n, m, dtwm_v, constr);
	  break;
	  
	default:
	  PyErr_SetString(PyExc_ValueError, "steppattern is not valid");
	  return NULL;
	}

      free(constr[0]);
      free(constr[1]);
      free(constr);          

      pathx = (int *) malloc((n + m - 1) * sizeof(int));
      pathy = (int *) malloc((n + m - 1) * sizeof(int));
      
      if (startbc == Py_True)
	sbc = 1;
      else
	sbc = 0;  
      
      k = optimal_warping_path(dtwm_v, n, m, pathx, pathy, sbc);
      
      p_dims[0] = (npy_intp) k;
      px_a = PyArray_SimpleNew(1, p_dims, NPY_INT);
      py_a = PyArray_SimpleNew(1, p_dims, NPY_INT);
      px_v = (int *) PyArray_DATA(px_a);
      py_v = (int *) PyArray_DATA(py_a);
      
      for (i=0; i<k; i++)
	{
	  px_v[i] = pathx[k-1-i];
	  py_v[i] = pathy[k-1-i];
	}
      
      free(pathx);
      free(pathy);
      
      Py_DECREF(x_a);
      Py_DECREF(y_a);
      
      return Py_BuildValue("d, N, N, N", distance, px_a, py_a, dtwm_a);
    }
}
Beispiel #26
0
int NI_ZoomShift(PyArrayObject *input, PyArrayObject* zoom_ar,
                                 PyArrayObject* shift_ar, PyArrayObject *output,
                                 int order, int mode, double cval)
{
    char *po, *pi;
    npy_intp **zeros = NULL, **offsets = NULL, ***edge_offsets = NULL;
    npy_intp ftmp[NPY_MAXDIMS], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp jj, hh, kk, filter_size, odimensions[NPY_MAXDIMS];
    npy_intp idimensions[NPY_MAXDIMS], istrides[NPY_MAXDIMS];
    npy_intp size;
    double ***splvals = NULL;
    NI_Iterator io;
    npy_double *zooms = zoom_ar ? (npy_double*)PyArray_DATA(zoom_ar) : NULL;
    npy_double *shifts = shift_ar ? (npy_double*)PyArray_DATA(shift_ar) : NULL;
    int rank = 0;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    for (kk = 0; kk < PyArray_NDIM(input); kk++) {
        idimensions[kk] = PyArray_DIM(input, kk);
        istrides[kk] = PyArray_STRIDE(input, kk);
        odimensions[kk] = PyArray_DIM(output, kk);
    }
    rank = PyArray_NDIM(input);

    /* if the mode is 'constant' we need some temps later: */
    if (mode == NI_EXTEND_CONSTANT) {
        zeros = malloc(rank * sizeof(npy_intp*));
        if (NPY_UNLIKELY(!zeros)) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
        for(jj = 0; jj < rank; jj++)
            zeros[jj] = NULL;
        for(jj = 0; jj < rank; jj++) {
            zeros[jj] = malloc(odimensions[jj] * sizeof(npy_intp));
            if (NPY_UNLIKELY(!zeros[jj])) {
                NPY_END_THREADS;
                PyErr_NoMemory();
                goto exit;
            }
        }
    }

    /* store offsets, along each axis: */
    offsets = malloc(rank * sizeof(npy_intp*));
    /* store spline coefficients, along each axis: */
    splvals = malloc(rank * sizeof(double**));
    /* store offsets at all edges: */
    edge_offsets = malloc(rank * sizeof(npy_intp**));
    if (NPY_UNLIKELY(!offsets || !splvals || !edge_offsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = NULL;
        splvals[jj] = NULL;
        edge_offsets[jj] = NULL;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = malloc(odimensions[jj] * sizeof(npy_intp));
        splvals[jj] = malloc(odimensions[jj] * sizeof(double*));
        edge_offsets[jj] = malloc(odimensions[jj] * sizeof(npy_intp*));
        if (NPY_UNLIKELY(!offsets[jj] || !splvals[jj] || !edge_offsets[jj])) {
            NPY_END_THREADS;
            PyErr_NoMemory();
            goto exit;
        }
        for(hh = 0; hh < odimensions[jj]; hh++) {
            splvals[jj][hh] = NULL;
            edge_offsets[jj][hh] = NULL;
        }
    }

    /* precalculate offsets, and offsets at the edge: */
    for(jj = 0; jj < rank; jj++) {
        double shift = 0.0, zoom = 0.0;
        if (shifts)
            shift = shifts[jj];
        if (zooms)
            zoom = zooms[jj];
        for(kk = 0; kk < odimensions[jj]; kk++) {
            double cc = (double)kk;
            if (shifts)
                cc += shift;
            if (zooms)
                cc *= zoom;
            cc = map_coordinate(cc, idimensions[jj], mode);
            if (cc > -1.0) {
                npy_intp start;
                if (zeros && zeros[jj])
                    zeros[jj][kk] = 0;
                if (order & 1) {
                    start = (npy_intp)floor(cc) - order / 2;
                } else {
                    start = (npy_intp)floor(cc + 0.5) - order / 2;
                }
                offsets[jj][kk] = istrides[jj] * start;
                if (start < 0 || start + order >= idimensions[jj]) {
                    edge_offsets[jj][kk] = malloc((order + 1) * sizeof(npy_intp));
                    if (NPY_UNLIKELY(!edge_offsets[jj][kk])) {
                        NPY_END_THREADS;
                        PyErr_NoMemory();
                        goto exit;
                    }
                    for(hh = 0; hh <= order; hh++) {
                        npy_intp idx = start + hh;
                        npy_intp len = idimensions[jj];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            npy_intp s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (npy_intp)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (npy_intp)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        edge_offsets[jj][kk][hh] = istrides[jj] * (idx - start);
                    }
                }
                if (order > 0) {
                    splvals[jj][kk] = malloc((order + 1) * sizeof(double));
                    if (NPY_UNLIKELY(!splvals[jj][kk])) {
                        NPY_END_THREADS;
                        PyErr_NoMemory();
                        goto exit;
                    }
                    spline_coefficients(cc, order, splvals[jj][kk]);
                }
            } else {
                zeros[jj][kk] = 1;
            }
        }
    }

    filter_size = 1;
    for(jj = 0; jj < rank; jj++)
        filter_size *= order + 1;

    if (!NI_InitPointIterator(output, &io))
        goto exit;

    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* store all coordinates and offsets with filter: */
    fcoordinates = malloc(rank * filter_size * sizeof(npy_intp));
    foffsets = malloc(filter_size * sizeof(npy_intp));
    if (NPY_UNLIKELY(!fcoordinates || !foffsets)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }

    for(jj = 0; jj < rank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < rank; jj++)
            fcoordinates[jj + hh * rank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = rank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }
    size = PyArray_SIZE(output);
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        npy_intp edge = 0, oo = 0, zero = 0;

        for(hh = 0; hh < rank; hh++) {
            if (zeros && zeros[hh][io.coordinates[hh]]) {
                /* we use constant border condition */
                zero = 1;
                break;
            }
            oo += offsets[hh][io.coordinates[hh]];
            if (edge_offsets[hh][io.coordinates[hh]])
                edge = 1;
        }

        if (!zero) {
            npy_intp *ff = fcoordinates;
            const int type_num = PyArray_TYPE(input);
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                npy_intp idx = 0;
                double coeff = 0.0;

                if (NPY_UNLIKELY(edge)) {
                    /* use precalculated edge offsets: */
                    for(jj = 0; jj < rank; jj++) {
                        if (edge_offsets[jj][io.coordinates[jj]])
                            idx += edge_offsets[jj][io.coordinates[jj]][ff[jj]];
                        else
                            idx += ff[jj] * istrides[jj];
                    }
                    idx += oo;
                } else {
                    /* use normal offsets: */
                    idx += oo + foffsets[hh];
                }
                switch (type_num) {
                    CASE_INTERP_COEFF(NPY_BOOL, npy_bool,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UBYTE, npy_ubyte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_USHORT, npy_ushort,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_UINT, npy_uint,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONG, npy_ulong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_ULONGLONG, npy_ulonglong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_BYTE, npy_byte,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_SHORT, npy_short,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_INT, npy_int,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONG, npy_long,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_LONGLONG, npy_longlong,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_FLOAT, npy_float,
                                      coeff, pi, idx);
                    CASE_INTERP_COEFF(NPY_DOUBLE, npy_double,
                                      coeff, pi, idx);
                default:
                    NPY_END_THREADS;
                    PyErr_SetString(PyExc_RuntimeError,
                                    "data type not supported");
                    goto exit;
                }
                /* calculate interpolated value: */
                for(jj = 0; jj < rank; jj++)
                    if (order > 0)
                        coeff *= splvals[jj][io.coordinates[jj]][ff[jj]];
                t += coeff;
                ff += rank;
            }
        } else {
            t = cval;
        }
        /* store output: */
        switch (PyArray_TYPE(output)) {
            CASE_INTERP_OUT(NPY_BOOL, npy_bool, po, t);
            CASE_INTERP_OUT_UINT(UBYTE, npy_ubyte, po, t);
            CASE_INTERP_OUT_UINT(USHORT, npy_ushort, po, t);
            CASE_INTERP_OUT_UINT(UINT, npy_uint, po, t);
            CASE_INTERP_OUT_UINT(ULONG, npy_ulong, po, t);
            CASE_INTERP_OUT_UINT(ULONGLONG, npy_ulonglong, po, t);
            CASE_INTERP_OUT_INT(BYTE, npy_byte, po, t);
            CASE_INTERP_OUT_INT(SHORT, npy_short, po, t);
            CASE_INTERP_OUT_INT(INT, npy_int, po, t);
            CASE_INTERP_OUT_INT(LONG, npy_long, po, t);
            CASE_INTERP_OUT_INT(LONGLONG, npy_longlong, po, t);
            CASE_INTERP_OUT(NPY_FLOAT, npy_float, po, t);
            CASE_INTERP_OUT(NPY_DOUBLE, npy_double, po, t);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(io, po);
    }

 exit:
    NPY_END_THREADS;
    if (zeros) {
        for(jj = 0; jj < rank; jj++)
            free(zeros[jj]);
        free(zeros);
    }
    if (offsets) {
        for(jj = 0; jj < rank; jj++)
            free(offsets[jj]);
        free(offsets);
    }
    if (splvals) {
        for(jj = 0; jj < rank; jj++) {
            if (splvals[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    free(splvals[jj][hh]);
                free(splvals[jj]);
            }
        }
        free(splvals);
    }
    if (edge_offsets) {
        for(jj = 0; jj < rank; jj++) {
            if (edge_offsets[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    free(edge_offsets[jj][hh]);
                free(edge_offsets[jj]);
            }
        }
        free(edge_offsets);
    }
    free(foffsets);
    free(fcoordinates);
    return PyErr_Occurred() ? 0 : 1;
}
Beispiel #27
0
Py::Object
_path_module::affine_transform(const Py::Tuple& args)
{
    args.verify_length(2);

    Py::Object vertices_obj = args[0];
    Py::Object transform_obj = args[1];

    PyArrayObject* vertices = NULL;
    PyArrayObject* transform = NULL;
    PyArrayObject* result = NULL;

    try
    {
        vertices = (PyArrayObject*)PyArray_FromObject
                   (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2);
        if (!vertices ||
            (PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 0) != 0 &&
             PyArray_DIM(vertices, 1) != 2) ||
            (PyArray_NDIM(vertices) == 1 &&
             PyArray_DIM(vertices, 0) != 2 && PyArray_DIM(vertices, 0) != 0))
        {
            throw Py::ValueError("Invalid vertices array.");
        }

        transform = (PyArrayObject*) PyArray_FromObject
                    (transform_obj.ptr(), PyArray_DOUBLE, 2, 2);
        if (!transform ||
            PyArray_DIM(transform, 0) != 3 ||
            PyArray_DIM(transform, 1) != 3)
        {
            throw Py::ValueError("Invalid transform.");
        }

        double a, b, c, d, e, f;
        {
            size_t stride0 = PyArray_STRIDE(transform, 0);
            size_t stride1 = PyArray_STRIDE(transform, 1);
            char* row0 = PyArray_BYTES(transform);
            char* row1 = row0 + stride0;

            a = *(double*)(row0);
            row0 += stride1;
            c = *(double*)(row0);
            row0 += stride1;
            e = *(double*)(row0);

            b = *(double*)(row1);
            row1 += stride1;
            d = *(double*)(row1);
            row1 += stride1;
            f = *(double*)(row1);
        }

        result = (PyArrayObject*)PyArray_SimpleNew
                 (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE);
        if (result == NULL)
        {
            throw Py::MemoryError("Could not allocate memory for path");
        }
        if (PyArray_NDIM(vertices) == 2)
        {
            size_t n = PyArray_DIM(vertices, 0);
            char* vertex_in = PyArray_BYTES(vertices);
            double* vertex_out = (double*)PyArray_DATA(result);
            size_t stride0 = PyArray_STRIDE(vertices, 0);
            size_t stride1 = PyArray_STRIDE(vertices, 1);
            double x;
            double y;

            for (size_t i = 0; i < n; ++i)
            {
                x = *(double*)(vertex_in);
                y = *(double*)(vertex_in + stride1);

                *vertex_out++ = a * x + c * y + e;
                *vertex_out++ = b * x + d * y + f;

                vertex_in += stride0;
            }
        }
        else if (PyArray_DIM(vertices, 0) != 0)
        {
            char* vertex_in = PyArray_BYTES(vertices);
            double* vertex_out = (double*)PyArray_DATA(result);
            size_t stride0 = PyArray_STRIDE(vertices, 0);
            double x;
            double y;
            x = *(double*)(vertex_in);
            y = *(double*)(vertex_in + stride0);
            *vertex_out++ = a * x + c * y + e;
            *vertex_out++ = b * x + d * y + f;
        }
    }
    catch (...)
    {
        Py_XDECREF(vertices);
        Py_XDECREF(transform);
        Py_XDECREF(result);
        throw;
    }

    Py_XDECREF(vertices);
    Py_XDECREF(transform);

    return Py::Object((PyObject*)result, true);
}
Beispiel #28
0
int APPLY_SPECIFIC(ave_pool_grad)(PyGpuArrayObject *x,
                                  PyGpuArrayObject *gz,
                                  PyArrayObject *ws,
                                  PyArrayObject *stride,
                                  PyArrayObject *pad,
                                  PyGpuArrayObject **gx,
                                  PyGpuContextObject *ctx) {
  if (!GpuArray_IS_C_CONTIGUOUS(&x->ga)
      || !GpuArray_IS_C_CONTIGUOUS(&gz->ga))
    {
      PyErr_Format(PyExc_ValueError,
                   "GpuMaxPoolGrad: requires data to be C-contiguous");
      return 1;
    }
  size_t ndims = PyArray_DIM(ws, 0);
  if (PyGpuArray_NDIM(x) != ndims + 2
      || PyGpuArray_NDIM(gz) != ndims + 2)
    {
      PyErr_SetString(PyExc_ValueError, "GpuMaxPoolGrad: rank error");
      return 1;
    }
  if (theano_prep_output(gx, PyGpuArray_NDIM(x), PyGpuArray_DIMS(x),
                         x->ga.typecode, GA_C_ORDER, ctx) != 0)
    {
      PyErr_SetString(PyExc_RuntimeError,
                      "GpuMaxPoolGrad: failed to allocate memory");
      return 1;
    }

  {
    // scope for running kernel
    size_t w[3];
    size_t s[3];
    size_t p[3];
    for(int i = 0; i < ndims; i++) {
      w[i] = *((npy_intp*)PyArray_GETPTR1(ws, i));
      s[i] = *((npy_intp*)PyArray_GETPTR1(stride, i));
      p[i] = *((npy_intp*)PyArray_GETPTR1(pad, i));
    }

    int err;
    const size_t* z_dims = PyGpuArray_DIMS(gz);
    const size_t* x_dims = PyGpuArray_DIMS(x);

    if (ndims == 2) {
      size_t num_kernels = x_dims[0] * x_dims[1] * x_dims[2] * x_dims[3];
      err = ave_pool2d_grad_kernel_scall(1, &num_kernels, 0, num_kernels,
                                         x_dims[0], x_dims[1], x_dims[2], x_dims[3],
                                         z_dims[2], z_dims[3],
                                         x->ga.data, gz->ga.data,
                                         w[0], w[1], s[0], s[1], p[0], p[1],
                                         INC_PAD, SUM_MODE, (*gx)->ga.data);
      if (err != GA_NO_ERROR) {
        PyErr_Format(PyExc_RuntimeError,
                     "GpuAveragePoolGrad: ave_pool2d_grad_kernel %s.",
                     GpuKernel_error(&k_ave_pool2d_grad_kernel, err));
        return 1;
      }
    } else if (ndims == 3) {
      size_t num_kernels = x_dims[0] * x_dims[1] * x_dims[2] * x_dims[3] * x_dims[4];
      err = ave_pool3d_grad_kernel_scall(1, &num_kernels, 0, num_kernels,
                                         x_dims[0], x_dims[1], x_dims[2], x_dims[3], x_dims[4],
                                         z_dims[2], z_dims[3], z_dims[4],
                                         x->ga.data, gz->ga.data,
                                         w[0], w[1], w[2], s[0], s[1], s[2],
                                         p[0], p[1], p[2], INC_PAD, SUM_MODE,
                                         (*gx)->ga.data);
      if (err != GA_NO_ERROR) {
        PyErr_Format(PyExc_RuntimeError,
                     "GpuAveragePoolGrad: ave_pool3d_grad_kernel %s.",
                     GpuKernel_error(&k_ave_pool3d_grad_kernel, err));
        return 1;
      }
    }
  }
  return 0;
}
Beispiel #29
0
Py::Object
_path_module::get_path_collection_extents(const Py::Tuple& args)
{
    args.verify_length(5);

    //segments, trans, clipbox, colors, linewidths, antialiaseds
    agg::trans_affine       master_transform = py_to_agg_transformation_matrix(args[0].ptr());
    Py::SeqBase<Py::Object> paths            = args[1];
    Py::SeqBase<Py::Object> transforms_obj   = args[2];
    Py::Object              offsets_obj      = args[3];
    agg::trans_affine       offset_trans     = py_to_agg_transformation_matrix(args[4].ptr(), false);

    PyArrayObject* offsets = NULL;
    double x0, y0, x1, y1, xm, ym;

    try
    {
        offsets = (PyArrayObject*)PyArray_FromObject(
            offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
        if (!offsets ||
            (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
            (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
        {
            throw Py::ValueError("Offsets array must be Nx2");
        }

        size_t Npaths      = paths.length();
        size_t Noffsets    = offsets->dimensions[0];
        size_t N               = std::max(Npaths, Noffsets);
        size_t Ntransforms = std::min(transforms_obj.length(), N);
        size_t i;

        // Convert all of the transforms up front
        typedef std::vector<agg::trans_affine> transforms_t;
        transforms_t transforms;
        transforms.reserve(Ntransforms);
        for (i = 0; i < Ntransforms; ++i)
        {
            agg::trans_affine trans = py_to_agg_transformation_matrix
                (transforms_obj[i].ptr(), false);
            trans *= master_transform;
            transforms.push_back(trans);
        }

        // The offset each of those and collect the mins/maxs
        x0 = std::numeric_limits<double>::infinity();
        y0 = std::numeric_limits<double>::infinity();
        x1 = -std::numeric_limits<double>::infinity();
        y1 = -std::numeric_limits<double>::infinity();
        xm = std::numeric_limits<double>::infinity();
        ym = std::numeric_limits<double>::infinity();
        agg::trans_affine trans;

        for (i = 0; i < N; ++i)
        {
            PathIterator path(paths[i % Npaths]);
            if (Ntransforms)
            {
                trans = transforms[i % Ntransforms];
            }
            else
            {
                trans = master_transform;
            }

            if (Noffsets)
            {
                double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
                double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
                offset_trans.transform(&xo, &yo);
                trans *= agg::trans_affine_translation(xo, yo);
            }

            ::get_path_extents(path, trans, &x0, &y0, &x1, &y1, &xm, &ym);
        }
    }
    catch (...)
    {
        Py_XDECREF(offsets);
        throw;
    }

    Py_XDECREF(offsets);

    Py::Tuple result(4);
    result[0] = Py::Float(x0);
    result[1] = Py::Float(y0);
    result[2] = Py::Float(x1);
    result[3] = Py::Float(y1);
    return result;
}
Beispiel #30
0
//apply_kernel3d() implementation
static PyObject *_apply_kernel3d(PyObject *args,double(*kernel)(double,double,double,double)){


	PyObject *positions_obj,*bins_obj,*weights_obj,*radius_obj,*concentration_obj;
	float *weights;
	double *radius,*concentration;

	//parse input tuple
	if(!PyArg_ParseTuple(args,"OOOOO",&positions_obj,&bins_obj,&weights_obj,&radius_obj,&concentration_obj)){
		return NULL;
	}

	//interpret parsed objects as arrays
	PyObject *positions_array = PyArray_FROM_OTF(positions_obj,NPY_FLOAT32,NPY_IN_ARRAY);
	PyObject *binsX_array = PyArray_FROM_OTF(PyTuple_GET_ITEM(bins_obj,0),NPY_DOUBLE,NPY_IN_ARRAY);
	PyObject *binsY_array = PyArray_FROM_OTF(PyTuple_GET_ITEM(bins_obj,1),NPY_DOUBLE,NPY_IN_ARRAY);
	PyObject *binsZ_array = PyArray_FROM_OTF(PyTuple_GET_ITEM(bins_obj,2),NPY_DOUBLE,NPY_IN_ARRAY);

	//check if anything failed
	if(positions_array==NULL || binsX_array==NULL || binsY_array==NULL || binsZ_array==NULL){
		
		Py_XDECREF(positions_array);
		Py_XDECREF(binsX_array);
		Py_XDECREF(binsY_array);
		Py_XDECREF(binsZ_array);

		return NULL;
	}

	//check if weights,radius,concentration are provided
	PyObject *weights_array,*radius_array,*concentration_array;
	
	if(weights_obj!=Py_None){
		
		weights_array = PyArray_FROM_OTF(weights_obj,NPY_FLOAT32,NPY_IN_ARRAY);
		
		if(weights_array==NULL){

			Py_DECREF(positions_array);
			Py_DECREF(binsX_array);
			Py_DECREF(binsY_array);
			Py_DECREF(binsZ_array);

			return NULL;

		}

		//Data pointer
		weights = (float *)PyArray_DATA(weights_array);

	} else{

		weights = NULL;
	}


	if(radius_obj!=Py_None){
		
		radius_array = PyArray_FROM_OTF(radius_obj,NPY_DOUBLE,NPY_IN_ARRAY);
		
		if(radius_array==NULL){

			Py_DECREF(positions_array);
			Py_DECREF(binsX_array);
			Py_DECREF(binsY_array);
			Py_DECREF(binsZ_array);
			if(weights) Py_DECREF(weights_array);

			return NULL;

		}

		//Data pointer
		radius = (double *)PyArray_DATA(radius_array);

	} else{

		radius = NULL;
	}


	if(concentration_obj!=Py_None){
		
		concentration_array = PyArray_FROM_OTF(concentration_obj,NPY_DOUBLE,NPY_IN_ARRAY);
		
		if(concentration_array==NULL){

			Py_DECREF(positions_array);
			Py_DECREF(binsX_array);
			Py_DECREF(binsY_array);
			Py_DECREF(binsZ_array);
			if(weights) Py_DECREF(weights_array);
			if(radius) Py_DECREF(radius_array);

			return NULL;

		}

		//Data pointer
		concentration = (double *)PyArray_DATA(concentration_array);

	} else{

		concentration = NULL;
	}

	//Get data pointers
	float *positions_data = (float *)PyArray_DATA(positions_array);
	double *binsX_data = (double *)PyArray_DATA(binsX_array);
	double *binsY_data = (double *)PyArray_DATA(binsY_array);
	double *binsZ_data = (double *)PyArray_DATA(binsZ_array);

	//Get info about the number of bins
	int NumPart = (int)PyArray_DIM(positions_array,0);
	int nx = (int)PyArray_DIM(binsX_array,0) - 1;
	int ny = (int)PyArray_DIM(binsY_array,0) - 1;
	int nz = (int)PyArray_DIM(binsZ_array,0) - 1;

	//Allocate the new array for the grid
	PyObject *grid_array;
		
	npy_intp gridDims[] = {(npy_intp) nx,(npy_intp) ny,(npy_intp) nz};
	grid_array = PyArray_ZEROS(3,gridDims,NPY_FLOAT32,0);

	if(grid_array==NULL){

		Py_DECREF(positions_array);
		Py_DECREF(binsX_array);
		Py_DECREF(binsY_array);
		Py_DECREF(binsZ_array);

		if(weights) Py_DECREF(weights_array);
		if(radius) Py_DECREF(radius_array);
		if(concentration) Py_DECREF(concentration_array);

		return NULL;

	}

	//Get a data pointer
	float *grid_data = (float *)PyArray_DATA(grid_array);

	//Snap the particles on the grid
	grid3d(positions_data,weights,radius,concentration,NumPart,binsX_data[0],binsY_data[0],binsZ_data[0],binsX_data[1] - binsX_data[0],binsY_data[1] - binsY_data[0],binsZ_data[1] - binsZ_data[0],nx,ny,nz,grid_data,kernel);

	//return the grid
	Py_DECREF(positions_array);
	Py_DECREF(binsX_array);
	Py_DECREF(binsY_array);
	Py_DECREF(binsZ_array);

	if(weights) Py_DECREF(weights_array);
	if(radius) Py_DECREF(radius_array);
	if(concentration) Py_DECREF(concentration_array);
	
	return grid_array;


}