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)); }
int relax_precision(const np::ndarray& predict, const np::ndarray& label, const int& relax) { const int h_lim = predict.shape(1); const int w_lim = predict.shape(0); const int32_t *predict_data = reinterpret_cast<int32_t *>(predict.get_data()); const int32_t *label_data = reinterpret_cast<int32_t *>(label.get_data()); int true_positive = 0; for (int y = 0; y < h_lim; ++y) { for (int x = 0; x < w_lim; ++x) { const int32_t pred_val = predict_data[y * w_lim + x]; if (pred_val == 1) { const int st_y = y - relax >= 0 ? y - relax : 0; const int en_y = y + relax < h_lim ? y + relax : h_lim - 1; const int st_x = x - relax >= 0 ? x - relax : 0; const int en_x = x + relax < w_lim ? x + relax : w_lim - 1; int sum = 0; for (int yy = st_y; yy <= en_y; ++yy) { for (int xx = st_x; xx <= en_x; ++xx) { sum += label_data[yy * w_lim + xx]; } } if (sum > 0) true_positive++; } } } return true_positive; }
// 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)); }
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); }