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; }
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); }
int main(int argc, char *argv[]) { int i, j; /* Loop control variables */ int bands; /* Number of image bands */ double *mu; /* Mean vector for image bands */ double **covar; /* Covariance Matrix */ double *eigval; double **eigmat; int *inp_fd; int scale, scale_max, scale_min; struct GModule *module; struct Option *opt_in, *opt_out, *opt_scale; /* initialize GIS engine */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("image transformation")); G_add_keyword(_("PCA")); module->description = _("Principal components analysis (PCA) " "for image processing."); /* Define options */ opt_in = G_define_standard_option(G_OPT_R_INPUTS); opt_in->description = _("Name of two or more input raster maps"); opt_out = G_define_option(); opt_out->label = _("Base name for output raster maps"); opt_out->description = _("A numerical suffix will be added for each component map"); opt_out->key = "output_prefix"; opt_out->type = TYPE_STRING; opt_out->key_desc = "string"; opt_out->required = YES; opt_scale = G_define_option(); opt_scale->key = "rescale"; opt_scale->type = TYPE_INTEGER; opt_scale->key_desc = "min,max"; opt_scale->required = NO; opt_scale->answer = "0,255"; opt_scale->label = _("Rescaling range for output maps"); opt_scale->description = _("For no rescaling use 0,0"); opt_scale->guisection = _("Rescale"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* determine number of bands passed in */ for (bands = 0; opt_in->answers[bands] != NULL; bands++) ; if (bands < 2) G_fatal_error(_("Sorry, at least 2 input bands must be provided")); /* default values */ scale = 1; scale_min = 0; scale_max = 255; /* get scale parameters */ set_output_scale(opt_scale, &scale, &scale_min, &scale_max); /* allocate memory */ covar = G_alloc_matrix(bands, bands); mu = G_alloc_vector(bands); inp_fd = G_alloc_ivector(bands); eigmat = G_alloc_matrix(bands, bands); eigval = G_alloc_vector(bands); /* open and check input/output files */ for (i = 0; i < bands; i++) { char tmpbuf[128]; sprintf(tmpbuf, "%s.%d", opt_out->answer, i + 1); G_check_input_output_name(opt_in->answers[i], tmpbuf, GR_FATAL_EXIT); inp_fd[i] = Rast_open_old(opt_in->answers[i], ""); } G_verbose_message(_("Calculating covariance matrix...")); calc_mu(inp_fd, mu, bands); calc_covariance(inp_fd, covar, mu, bands); for (i = 0; i < bands; i++) { for (j = 0; j < bands; j++) { covar[i][j] = covar[i][j] / ((double)((Rast_window_rows() * Rast_window_cols()) - 1)); G_debug(3, "covar[%d][%d] = %f", i, j, covar[i][j]); } } G_math_d_copy(covar[0], eigmat[0], bands*bands); G_debug(1, "Calculating eigenvalues and eigenvectors..."); G_math_eigen(eigmat, eigval, bands); #ifdef PCA_DEBUG /* dump eigen matrix and eigen values */ dump_eigen(bands, eigmat, eigval); #endif G_debug(1, "Ordering eigenvalues in descending order..."); G_math_egvorder(eigval, eigmat, bands); G_debug(1, "Transposing eigen matrix..."); G_math_d_A_T(eigmat, bands); /* write output images */ write_pca(eigmat, inp_fd, opt_out->answer, bands, scale, scale_min, scale_max); /* write colors and history to output */ for (i = 0; i < bands; i++) { char outname[80]; sprintf(outname, "%s.%d", opt_out->answer, i + 1); /* write colors and history to file */ write_support(bands, outname, eigmat, eigval); /* close output file */ Rast_unopen(inp_fd[i]); } /* free memory */ G_free_matrix(covar); G_free_vector(mu); G_free_ivector(inp_fd); G_free_matrix(eigmat); G_free_vector(eigval); exit(EXIT_SUCCESS); }