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; }
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; }
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; }
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); }
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)); }
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; }
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; }
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; }
/* * 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 }
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; } )
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; }
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)
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); }
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; }
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; }
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; }
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; }
/* 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; }
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; } }
/* 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; }
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); }
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; }
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); } }
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; }
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); }
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; }
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; }
//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; }