nd::array nd::view(const nd::array &arr, const ndt::type &tp) { if (arr.get_type() == tp) { // If the types match exactly, simply return 'arr' return arr; } else if (tp.get_type_id() == bytes_type_id) { // If it's a request to view the data as raw bytes nd::array result = view_as_bytes(arr, tp); if (!result.is_null()) { return result; } } else if (arr.get_type().get_type_id() == bytes_type_id) { // If it's a request to view raw bytes as something else nd::array result = view_from_bytes(arr, tp); if (!result.is_null()) { return result; } } else if (arr.get_ndim() == tp.get_ndim()) { // If the type is symbolic, e.g. has a "Fixed" symbolic dimension, // first substitute in the shape from the array if (tp.is_symbolic()) { dimvector shape(arr.get_ndim()); arr.get_shape(shape.get()); return view_concrete(arr, substitute_shape(tp, arr.get_ndim(), shape.get())); } else { return view_concrete(arr, tp); } } stringstream ss; ss << "Unable to view nd::array of type " << arr.get_type(); ss << " as type " << tp; throw type_error(ss.str()); }
nd::array nd::view(const nd::array& arr, const ndt::type& tp) { // If the types match exactly, simply return 'arr' if (arr.get_type() == tp) { return arr; } else if (arr.get_ndim() == tp.get_ndim()) { // Allocate a result array to attempt the view in it array result(make_array_memory_block(tp.get_metadata_size())); // Copy the fields result.get_ndo()->m_data_pointer = arr.get_ndo()->m_data_pointer; if (arr.get_ndo()->m_data_reference == NULL) { // Embedded data, need reference to the array result.get_ndo()->m_data_reference = arr.get_memblock().release(); } else { // Use the same data reference, avoid producing a chain result.get_ndo()->m_data_reference = arr.get_data_memblock().release(); } result.get_ndo()->m_type = ndt::type(tp).release(); result.get_ndo()->m_flags = arr.get_ndo()->m_flags; // Now try to copy the metadata as a view if (try_view(arr.get_type(), arr.get_ndo_meta(), tp, result.get_ndo_meta(), arr.get_memblock().get())) { // If it succeeded, return it return result; } // Otherwise fall through, let it get destructed, and raise an error } stringstream ss; ss << "Unable to view nd::array of type " << arr.get_type(); ss << "as type " << tp; throw type_error(ss.str()); }
inline nd::array ifft(const nd::array &x, std::vector<intptr_t> shape) { std::vector<intptr_t> axes; for (intptr_t i = 0; i < x.get_ndim(); ++i) { axes.push_back(i); } return ifft(x, shape, axes); }
nd::array nd::fftshift(const nd::array &x) { nd::array y = x; for (intptr_t i = 0; i < x.get_ndim(); ++i) { intptr_t p = y.get_dim_size(); intptr_t q = (p + 1) / 2; y = take(y, nd::concatenate(nd::range(q, p), nd::range(q))); y = y.rotate(); } return y; }
/** * Computes the discrete inverse Fourier transform of a complex array, under the * assumption that the result is a real array. * * @param x An array of real numbers with arbitrary dimensions. * @param shape The shape of the Fourier transform. If any dimension is less than * the corresponding dimension of 'x', that dimension will be truncated. * * @return A complex array with dimensions specified by 'shape'. By default, the shape * is the same as that of 'x', except the last dimension is '2 * (x.get_shape[x.get_ndim() - 1] - 1)'. */ inline nd::array irfft(const nd::array &x, std::vector<intptr_t> shape) { if (x.get_ndim() != static_cast<intptr_t>(shape.size())) { throw std::invalid_argument("dimensions provided for irfft do not match"); } #ifdef DYND_FFTW return fftw::irfft(x, shape); #else throw std::runtime_error("irfft is not implemented"); #endif }