float simple_liner_regression(np::ndarray a, np::ndarray b, np::ndarray c) { int nd1 = a.get_nd(); int nd2 = b.get_nd(); if (nd1 != 1 || nd2 != 1) throw std::runtime_error("a and b must be 1-dimensional"); if ( (a.get_dtype() != np::dtype::get_builtin<double>()) || (b.get_dtype() != np::dtype::get_builtin<double>()) ) throw std::runtime_error("a and b must be float64 array"); size_t N = a.shape(0); if ( N != b.shape(0) ) throw std::runtime_error(" a and b must be same size"); double *p = reinterpret_cast<double *>(a.get_data()); std::vector<float> x; for(int i=0;i<N;i++) x.push_back(*p++); double *q = reinterpret_cast<double *>(b.get_data()); std::vector<float> y; for(int i=0;i<N;i++) y.push_back(*q++); // 回帰系数の計算 float a1 = calc_covariance(x,y) / calc_variance(x); float a0 = calc_mean(y) - a1 * calc_mean(x); double *r = reinterpret_cast<double *>(c.get_data()); *r = a0; r++; *r = a1; }
// Here's a simple wrapper function for fill1. It requires that the passed // NumPy array be exactly what we're looking for - no conversion from nested // sequences or arrays with other data types, because we want to modify it // in-place. void wrap_fill1(np::ndarray const & array) { if (array.get_dtype() != np::dtype::get_builtin<double>()) { PyErr_SetString(PyExc_TypeError, "Incorrect array data type"); p::throw_error_already_set(); } if (array.get_nd() != 2) { PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions"); p::throw_error_already_set(); } fill1(reinterpret_cast<double*>(array.get_data()), array.shape(0), array.shape(1), array.strides(0) / sizeof(double), array.strides(1) / sizeof(double)); }
NumPyArrayData<T>(const np::ndarray &arr){ np::dtype dtype = arr.get_dtype(); np::dtype dtype_expected = np::dtype::get_builtin<T>(); if(dtype != dtype_expected) { std::stringstream ss; ss << "NumPyArrayData: Unexpected data type (" << bp::extract<const char*>(dtype.attr("__str__")()) << ") received"; ss << "Expected " << bp::extract<const char*>(dtype_expected.attr("__str__")()); throw std::runtime_error(ss.str().c_str()); } data_ = arr.get_data(); strides_ = arr.get_strides(); }
float u_variance(np::ndarray a) { int nd = a.get_nd(); if (nd != 1) throw std::runtime_error("a must be 1-dimensional"); if (a.get_dtype() != np::dtype::get_builtin<double>()) throw std::runtime_error("a must be float64 array"); size_t N = a.shape(0); double *p = reinterpret_cast<double *>(a.get_data()); std::vector<float> x; for(int i=0;i<N;i++) x.push_back(*p++); return calc_u_variance(x); }
float covariance(np::ndarray a, np::ndarray b) { int nd1 = a.get_nd(); int nd2 = b.get_nd(); if (nd1 != 1 || nd2 != 1) throw std::runtime_error("a and b must be 1-dimensional"); if ( (a.get_dtype() != np::dtype::get_builtin<double>()) || (b.get_dtype() != np::dtype::get_builtin<double>()) ) throw std::runtime_error("a and b must be float64 array"); size_t N = a.shape(0); if ( N != b.shape(0) ) throw std::runtime_error(" a and b must be same size"); double *p = reinterpret_cast<double *>(a.get_data()); std::vector<float> x; for(int i=0;i<N;i++) x.push_back(*p++); double *q = reinterpret_cast<double *>(b.get_data()); std::vector<float> y; for(int i=0;i<N;i++) y.push_back(*q++); return calc_covariance(x,y); }
// Here's the wrapper for fill2; it's a little more complicated because we need // to check the flags and create the array of pointers. void wrap_fill2(np::ndarray const & array) { if (array.get_dtype() != np::dtype::get_builtin<double>()) { PyErr_SetString(PyExc_TypeError, "Incorrect array data type"); p::throw_error_already_set(); } if (array.get_nd() != 2) { PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions"); p::throw_error_already_set(); } if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) { PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous"); p::throw_error_already_set(); } double * iter = reinterpret_cast<double*>(array.get_data()); int rows = array.shape(0); int cols = array.shape(1); boost::scoped_array<double*> ptrs(new double*[rows]); for (int i = 0; i < rows; ++i, iter += cols) { ptrs[i] = iter; } fill2(ptrs.get(), array.shape(0), array.shape(1)); }