home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)trend2d.c 2.12 3/13/95
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * trend2d.c [<xyz[w]file>] -F<output_flags> -N<n_m_parameters>[r]
- * [-C<condition_#>] [-I[<confid>]] [-V] [-W]
- *
- * where:
- * [<xyz[w]file>] is an ascii file with x y z in first 3 columns
- * [or x y z w in first 4 columns]. Default reads from stdin.
- * -F<output_flags> is a string of at least one, up to five, in
- * and order, from the set {x y z m r w}. x,y,z = input,
- * m = model, r = residual = z-m, and w= weight used.
- * -N<n_m_parameters>[r]
- * If iterative Robust fitting desired, use -N<#>r, else -N.
- * [Max] Number of terms in the model is <n_m_parameters>.
- * Example: Robust bilinear surface: -N4r. Max n = 10.
- * [-C<condition_#>] Cut off eigenvalue spectrum; use only eigen-
- * values such that (lambda_max / lambda[i]) < condition_#.
- * [-I[<confid>]] Iteratively Increment the number of model parameters,
- * searching for the significant model size, up to a maximum
- * set by <n_m_parameters>. We start with a 1 parameter
- * model and then iteratively increase the number of
- * model parameters, m, while m <= <n_m_parameters> &&
- * reduction in variance from i to i+1 is significant
- * at the <confid> level according to F test. If user sets
- * -I without giving <confid> then <confid> = 0.95.
- * [-V] Verbose operation.
- * [-W] Weighted data are input. Read 4 cols and use 4th as weight.
- *
- *
- * Read stdin or file of x y z triples, or weighted data, x y z w. Fit
- * a regression model z = f(x,y) + e, where e are error misfits and f(x,y)
- * has some user-prescribed functional form. The user may choose the number
- * of terms in the model to fit, whether to seek iterative refinement robust
- * w.r.t. outliers, and whether to seek automatic discovery of the significant
- * number of model parameters.
- *
- * Adapted from trend1d by w. h. f. smith.
- *
- *
- * During model fitting the data x,y coordinates are normalized into the domain
- * [-1, 1] for Chebyshev Polynomial fitting. Before writing out the data the
- * coordinates are rescaled to match the original input values.
- *
- *
- * Author: W. H. F. Smith
- * Date: 17 June 1991-1995.
- */
-
- #include "gmt.h"
-
- #define N_OUTPUT_CHOICES 6
-
- struct DATA {
- double x;
- double y;
- double z;
- double m;
- double r;
- double w;
- } *data;
-
- char format[20];
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- void read_data(), write_output(), transform_x(), untransform_x(), recompute_weights();
- void allocate_array_space(), free_the_memory(), calc_m_and_r(), move_model_a_to_b();
- void load_gtg_and_gtd(), solve_system();
-
- int i, j, n_data, n_outputs, n_model, n_model_max, np, significant, rank;
- BOOLEAN error = FALSE, weighted_input = FALSE, weighted_output = FALSE, robust = FALSE, increment = FALSE;
-
- double c_no = 1.0e06; /* Condition number for matrix solution */
- double confid = 0.51; /* Confidence interval for significance test */
- double *gtg, *v, *gtd, *lambda, *workb, *workz, *c_model, *o_model, *w_model, *work; /* Arrays */
- double xmin, xmax, ymin, ymax, c_chisq, o_chisq, w_chisq, scale = 1.0, prob;
- double get_chisq();
-
- char output_choice[N_OUTPUT_CHOICES];
- FILE *fp = NULL;
-
- argc = gmt_begin (argc, argv);
-
- n_outputs = 0;
- n_model_max = 0;
- for (i = 0; i < N_OUTPUT_CHOICES; i++) output_choice[i] = 0;
- sprintf (format, "%s\t\0", gmtdefs.d_format);
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- /* Common parameters */
-
- case 'H':
- case 'V':
- case ':':
- case '\0':
- error += get_common_args (argv[i], 0, 0, 0, 0);
- break;
-
- /* Supplemental parameters */
-
-
- case 'F':
- j = 2;
- while (argv[i][j]) {
- switch (argv[i][j]) {
- case 'x':
- output_choice[j-2] = 'x';
- break;
- case 'y':
- output_choice[j-2] = 'y';
- break;
- case 'z':
- output_choice[j-2] = 'z';
- break;
- case 'm':
- output_choice[j-2] = 'm';
- break;
- case 'r':
- output_choice[j-2] = 'r';
- break;
- case 'w':
- output_choice[j-2] = 'w';
- weighted_output = TRUE;
- break;
- default:
- error = TRUE;
- fprintf (stderr, "%s: GMT SYNTAX ERROR -F option. Unrecognized output choice %c\n", gmt_program, argv[i][j]);
- break;
- }
- n_outputs++;
- j++;
- }
- break;
- case 'C':
- c_no = atof(&argv[i][2]);
- break;
- case 'I':
- increment = TRUE;
- confid = (argv[i][2]) ? atof(&argv[i][2]) : 0.51;
- break;
- case 'N':
- if (argv[i][strlen (argv[i]) - 1] == 'r') robust = TRUE;
- n_model_max = (argv[i][2]) ? atoi(&argv[i][2]) : 0;
- break;
- case 'W':
- weighted_input = TRUE;
- break;
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else {
- if ((fp = fopen(argv[i], "r")) == NULL) {
- fprintf (stderr, "trend2d: Could not open file %s\n", argv[i]);
- error = TRUE;
- }
- }
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf(stderr,"trend2d %s - Fit a [weighted] [robust] polynomial for z = f(x,y) to ascii xyz[w]\n\n", GMT_VERSION);
- fprintf(stderr,"usage: trend2d -N<n_model>[r] [<xyz[w]file>] [-F<xymrw>] [-C<condition_#>] [-I[<confidence>]] [-V] [-W]\n\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf(stderr,"\t-N<n_model>[r] fit a [robust] model with <n_model> terms. <n_model> in [1,10]. E.g., robust quadratic = -N3r.\n");
- fprintf (stderr, "\n\tOPTIONS:\n");
- fprintf(stderr,"\t[<xyz[w]file>] name of ascii file, first 2 cols = x y [3 cols = x y w]. [Default reads stdin].\n");
- fprintf(stderr,"\t-F<xymrw> Choose at least 1, up to 6, any order, of xyzmrw for ascii output to stdout.\n");
- fprintf(stderr,"\t\tx=x, y=y, z=z, m=model, r=residual=z-m, w=weight. w determined iteratively if robust fit used.\n");
- fprintf(stderr,"\t-C Truncate eigenvalue spectrum so matrix has <condition_#>. [Default = 1.0e06].\n");
- fprintf(stderr,"\t-I Iteratively Increase # model parameters, to a max of <n_model> so long as the\n");
- fprintf(stderr,"\t\treduction in variance is significant at the <confidence> level.\n");
- fprintf(stderr,"\t\tGive -I without a number to default to 0.51 confidence level.\n");
- fprintf(stderr,"\t-V Verbose operation. Program reports progress to stderr.\n");
- fprintf(stderr,"\t-W Weighted input given, weights in 4th column. [Default is unweighted].\n\n");
- exit(-1);
- }
-
- if (c_no <= 1.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -C option. Condition number must be larger than unity\n", gmt_program);
- error++;
- }
- if (confid < 0.0 || confid > 1.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -C option. Give 0 < confidence level < 1.0\n", gmt_program);
- error++;
- }
- if (n_outputs > N_OUTPUT_CHOICES) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -F option. Too many output columns specified (%d)\n", gmt_program, n_outputs);
- error++;
- }
- if (n_model_max <= 0 || n_model_max > 10) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -N option. Must request 1-10 parameters\n", gmt_program);
- error++;
- }
-
- if (error) exit (-1);
-
- np = n_model_max; /* Row dimension for matrices gtg and v */
- allocate_array_space(np, >g, &v, >d, &lambda, &workb, &workz, &c_model, &o_model, &w_model);
-
- read_data(&data, &n_data, &xmin, &xmax, &ymin, &ymax, weighted_input, &work, fp);
-
- if (xmin == xmax || ymin == ymax) {
- fprintf(stderr,"trend2d: Fatal error in input data. X min = X max.\n");
- exit(-1);
- }
- if (n_data == 0) {
- fprintf(stderr,"trend2d: Fatal error. Could not read any data.\n");
- exit(-1);
- }
- if (n_data < n_model_max) {
- fprintf(stderr,"trend2d: Warning. Ill-posed problem. n_data < n_model_max.\n");
- }
-
- transform_x(data, n_data, xmin, xmax, ymin, ymax); /* Set domain to [-1, 1] or [-pi, pi] */
-
- if (gmtdefs.verbose) {
- fprintf(stderr,"trend2d: Read %d data with X values from %.8lg to %.8lg\n", n_data, xmin, xmax);
- fprintf(stderr,"N_model\tRank\tChi_Squared\tSignificance\n");
- }
-
- if (increment) {
- n_model = 1;
-
- /* Fit first model */
- load_gtg_and_gtd(data, n_data, gtg, gtd, workb, n_model, np);
- solve_system(gtg, gtd, c_model, n_model, np, lambda, v, workb, workz, c_no, &rank);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- c_chisq = get_chisq(data, n_data, n_model);
- if (gmtdefs.verbose) fprintf(stderr,"%d\t%d\t%.8lg\t%d\n", n_model, rank, c_chisq, 1);
- if (robust) {
- do {
- recompute_weights(data, n_data, work, &scale);
- move_model_a_to_b(c_model, w_model, n_model, &c_chisq, &w_chisq);
- load_gtg_and_gtd(data, n_data, gtg, gtd, workb, n_model, np);
- solve_system(gtg, gtd, c_model, n_model, np, lambda, v, workb, workz, c_no, &rank);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- c_chisq = get_chisq(data, n_data, n_model);
- significant = sig_f(c_chisq, n_data-n_model, w_chisq, n_data-n_model, confid, &prob);
- if (gmtdefs.verbose) fprintf(stderr,"%d\t%d\t%.8lg\t%.3lg\n", n_model, rank, c_chisq, prob);
- } while (significant);
- /* Go back to previous model only if w_chisq < c_chisq */
- if (w_chisq < c_chisq) {
- move_model_a_to_b(w_model, c_model, n_model, &w_chisq, &c_chisq);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- if (weighted_output && n_model == n_model_max) recompute_weights(data, n_data, work, &scale);
- }
- }
- /* First [robust] model has been found */
-
- significant = TRUE;
- while(n_model < n_model_max && significant) {
- move_model_a_to_b(c_model, o_model, n_model, &c_chisq, &o_chisq);
- n_model++;
-
- /* Fit next model */
- load_gtg_and_gtd(data, n_data, gtg, gtd, workb, n_model, np);
- solve_system(gtg, gtd, c_model, n_model, np, lambda, v, workb, workz, c_no, &rank);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- c_chisq = get_chisq(data, n_data, n_model);
- if (gmtdefs.verbose) fprintf(stderr,"%d\t%d\t%.8lg\t%.3lg\n", n_model, rank, c_chisq, 1.00);
- if (robust) {
- do {
- recompute_weights(data, n_data, work, &scale);
- move_model_a_to_b(c_model, w_model, n_model, &c_chisq, &w_chisq);
- load_gtg_and_gtd(data, n_data, gtg, gtd, workb, n_model, np);
- solve_system(gtg, gtd, c_model, n_model, np, lambda, v, workb, workz, c_no, &rank);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- c_chisq = get_chisq(data, n_data, n_model);
- significant = sig_f(c_chisq, n_data-n_model, w_chisq, n_data-n_model, confid, &prob);
- if (gmtdefs.verbose) fprintf(stderr,"%d\t%d\t%.8lg\t%.3lg\n", n_model, rank, c_chisq, prob);
- } while (significant);
- /* Go back to previous model only if w_chisq < c_chisq */
- if (w_chisq < c_chisq) {
- move_model_a_to_b(w_model, c_model, n_model, &w_chisq, &c_chisq);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- if (weighted_output && n_model == n_model_max) recompute_weights(data, n_data, work, &scale);
- }
- }
- /* Next [robust] model has been found */
- significant = sig_f(c_chisq, n_data-n_model, o_chisq, n_data-n_model-1, confid, &prob);
- }
-
- if (!(significant) ) { /* Go back to previous [robust] model, stored in o_model */
- n_model--;
- rank--;
- move_model_a_to_b(o_model, c_model, n_model, &o_chisq, &c_chisq);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- if (robust && weighted_output) recompute_weights(data, n_data, work, &scale);
- }
- }
- else {
- n_model = n_model_max;
- load_gtg_and_gtd(data, n_data, gtg, gtd, workb, n_model, np);
- solve_system(gtg, gtd, c_model, n_model, np, lambda, v, workb, workz, c_no, &rank);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- c_chisq = get_chisq(data, n_data, n_model);
- if (gmtdefs.verbose) fprintf(stderr,"%d\t%d\t%.8lg\t%.3lg\n", n_model, rank, c_chisq, 1.00);
- if (robust) {
- do {
- recompute_weights(data, n_data, work, &scale);
- move_model_a_to_b(c_model, w_model, n_model, &c_chisq, &w_chisq);
- load_gtg_and_gtd(data, n_data, gtg, gtd, workb, n_model, np);
- solve_system(gtg, gtd, c_model, n_model, np, lambda, v, workb, workz, c_no, &rank);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- c_chisq = get_chisq(data, n_data, n_model);
- significant = sig_f(c_chisq, n_data-n_model, w_chisq, n_data-n_model, confid, &prob);
- if (gmtdefs.verbose) fprintf(stderr,"%d\t%d\t%.8lg\t%.3lg\n", n_model, rank, c_chisq, prob);
- } while (significant);
- /* Go back to previous model only if w_chisq < c_chisq */
- if (w_chisq < c_chisq) {
- move_model_a_to_b(w_model, c_model, n_model, &w_chisq, &c_chisq);
- calc_m_and_r(data, n_data, c_model, n_model, workb);
- if (weighted_output && n_model == n_model_max) recompute_weights(data, n_data, work, &scale);
- }
- }
- }
-
- if (gmtdefs.verbose) {
- fprintf(stderr,"Final model stats: N model parameters %d. Rank %d. Chi-Squared: %.8lg\n", n_model, rank, c_chisq);
- fprintf(stderr,"Model Coefficients:");
- for (i = 0; i < n_model; i++) {
- fprintf(stderr, format, c_model[i]);
- }
- fprintf(stderr,"\n");
- }
-
- untransform_x(data, n_data, xmin, xmax, ymin, ymax);
-
- write_output(data, n_data, output_choice, n_outputs);
-
- free_the_memory(gtg, v, gtd, lambda, workb, workz, c_model, o_model, w_model, data, work);
-
- gmt_end (argc, argv);
- }
-
- void read_data(data, n_data, xmin, xmax, ymin, ymax, weighted_input, work, fp)
- struct DATA **data;
- int *n_data, weighted_input;
- double *xmin, *xmax, *ymin, *ymax, **work;
- FILE *fp;
- {
-
- int i = 0, ix, iy, n_alloc = GMT_CHUNK;
- char buffer[512];
- double xy[2];
-
- if (fp == NULL) fp = stdin;
- (*data) = (struct DATA *) memory (CNULL, n_alloc, sizeof(struct DATA), "trend1d");
- ix = (gmtdefs.xy_toggle) ? 1 : 0; iy = 1 - ix; /* Set up which columns have x and y */
-
- while ( (fgets (buffer, 512, fp) ) != NULL) {
- if ((sscanf(buffer, "%lf %lf %lf %lf", &xy[ix], &xy[iy], &(*data)[i].z, &(*data)[i].w)) != (3+weighted_input)) {
- fprintf(stderr,"trend2d: Cannot read x y z [w] from line %d\n", i+1);
- continue;
- }
- (*data)[i].x = xy[0];
- (*data)[i].y = xy[1];
- if (!(weighted_input)) (*data)[i].w = 1.0;
-
- if (i) {
- if (*xmin > (*data)[i].x) *xmin = (*data)[i].x;
- if (*xmax < (*data)[i].x) *xmax = (*data)[i].x;
- if (*ymin > (*data)[i].y) *ymin = (*data)[i].y;
- if (*ymax < (*data)[i].y) *ymax = (*data)[i].y;
- }
- else {
- *xmin = (*data)[i].x;
- *xmax = (*data)[i].x;
- *ymin = (*data)[i].y;
- *ymax = (*data)[i].y;
- }
- i++;
-
- if (i == n_alloc) {
- n_alloc += GMT_CHUNK;
- *data = (struct DATA *) memory ((char *)*data, n_alloc, sizeof(struct DATA), "trend1d");
- }
- }
- if (fp != stdin) fclose(fp);
- *data = (struct DATA *) memory ((char *)*data, i, sizeof(struct DATA), "trend1d");
- *work = (double *) memory (CNULL, i, sizeof(double), "trend1d");
- *n_data = i;
- }
-
- void allocate_array_space(np, gtg, v, gtd, lambda, workb, workz, c_model, o_model, w_model)
- int np;
- double **gtg, **v, **gtd, **lambda, **workb, **workz, **c_model, **o_model, **w_model;
- {
- *gtg = (double *) memory (CNULL, np*np, sizeof(double), "trend1d");
- *v = (double *) memory (CNULL, np*np, sizeof(double), "trend1d");
- *gtd = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- *lambda = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- *workb = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- *workz = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- *c_model = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- *o_model = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- *w_model = (double *) memory (CNULL, np, sizeof(double), "trend1d");
- }
-
- void write_output(data, n_data, output_choice, n_outputs)
- struct DATA *data;
- int n_data, n_outputs;
- char *output_choice;
- {
- int i, j;
- char format1[20], format2[20];
-
- sprintf (format1, "%s\t\0", gmtdefs.d_format);
- sprintf (format2, "%s\n\0", gmtdefs.d_format);
-
- for (i = 0; i < n_data; i++) {
- for (j = 0; j < n_outputs-1; j++) {
- switch (output_choice[j]) {
- case 'x':
- printf(format1, data[i].x);
- break;
- case 'y':
- printf(format1, data[i].y);
- break;
- case 'z':
- printf(format1, data[i].z);
- break;
- case 'm':
- printf(format1, data[i].m);
- break;
- case 'r':
- printf(format1, data[i].r);
- break;
- case 'w':
- printf(format1, data[i].w);
- break;
- }
- }
- switch (output_choice[j]) {
- case 'x':
- printf(format2, data[i].x);
- break;
- case 'y':
- printf(format2, data[i].y);
- break;
- case 'z':
- printf(format2, data[i].z);
- break;
- case 'm':
- printf(format2, data[i].m);
- break;
- case 'r':
- printf(format2, data[i].r);
- break;
- case 'w':
- printf(format2, data[i].w);
- break;
- }
- }
- }
-
- void free_the_memory(gtg, v, gtd, lambda, workb, workz, c_model, o_model, w_model, data, work)
- double *gtg, *v, *gtd, *lambda, *workb, *workz, *c_model, *o_model, *w_model, *work;
- struct DATA *data;
- {
- free ( (char *)work);
- free ( (char *)data);
- free ( (char *)w_model);
- free ( (char *)o_model);
- free ( (char *)c_model);
- free ( (char *)workz);
- free ( (char *)workb);
- free ( (char *)lambda);
- free ( (char *)gtd);
- free ( (char *)v);
- free ( (char *)gtg);
- }
-
- void transform_x(data, n_data, xmin, xmax, ymin, ymax)
- struct DATA *data;
- int n_data;
- double xmin, xmax, ymin, ymax;
- {
- int i;
- double offsetx, scalex;
- double offsety, scaley;
-
- offsetx = 0.5 * (xmin + xmax); /* Mid Range */
- offsety = 0.5 * (ymin + ymax);
- scalex = 2.0 / (xmax - xmin); /* 1 / (1/2 Range) */
- scaley = 2.0 / (ymax - ymin);
-
- for (i = 0; i < n_data; i++) {
- data[i].x = (data[i].x - offsetx) * scalex;
- data[i].y = (data[i].y - offsety) * scaley;
- }
- }
-
- void untransform_x(data, n_data, xmin, xmax, ymin, ymax)
- struct DATA *data;
- int n_data;
- double xmin, xmax, ymin, ymax;
- {
- int i;
- double offsetx, scalex;
- double offsety, scaley;
-
- offsetx = 0.5 * (xmin + xmax); /* Mid Range */
- offsety = 0.5 * (ymin + ymax);
- scalex = 0.5 * (xmax - xmin); /* 1/2 Range */
- scaley = 0.5 * (ymax - ymin);
-
- for (i = 0; i < n_data; i++) {
- data[i].x = (data[i].x * scalex) + offsetx;
- data[i].y = (data[i].y * scaley) + offsety;
- }
- }
-
- double get_chisq(data, n_data, n_model)
- struct DATA *data;
- int n_data, n_model;
- {
- int i, nu;
- double chi = 0.0;
-
-
- for (i = 0; i < n_data; i++) { /* Weight is already squared */
- if (data[i].w == 1.0) {
- chi += (data[i].r * data[i].r);
- }
- else {
- chi += (data[i].r * data[i].r * data[i].w);
- }
- }
- nu = n_data - n_model;
- if (nu > 1) return(chi/nu);
- return(chi);
- }
-
- void recompute_weights(data, n_data, work, scale)
- struct DATA *data;
- int n_data;
- double *work, *scale;
- {
- int i;
- double k, ksq, rr;
-
- /* First find median { fabs(data[].r) },
- estimate scale from this,
- and compute chisq based on this. */
-
- for (i = 0; i < n_data; i++) {
- work[i] = fabs(data[i].r);
- }
- qsort( (char *)work, n_data, sizeof(double), comp_double_asc);
-
- if (n_data%2) {
- *scale = 1.4826 * work[n_data/2];
- }
- else {
- *scale = 0.7413 * (work[n_data/2 - 1] + work[n_data/2]);
- }
-
- k = 1.5 * (*scale); /* Huber[1964] weight; 95% efficient for Normal data */
- ksq = k * k;
-
- for (i = 0; i < n_data; i++) {
- rr = fabs(data[i].r);
- if (rr <= k) {
- data[i].w = 1.0;
- }
- else {
- data[i].w = (2*k/rr) - (ksq/(rr*rr) ); /* This is really w-squared */
- }
- }
- }
-
- void load_g_row(x, y, n, gr)
- double x, y; /* Current data position, appropriately normalized. */
- int n; /* Number of model parameters, and elements of gr[] */
- double gr[]; /* Elements of row of G matrix. */
- {
- /* Routine computes the elements gr[j] in the ith row of the
- G matrix (Menke notation), where x,y is the ith datum's
- location. */
-
- int j;
-
- j = 0;
- while (j < n) {
- switch (j) {
- case 0:
- gr[j] = 1.0;
- break;
- case 1:
- gr[j] = x;
- break;
- case 2:
- gr[j] = y;
- break;
- case 3:
- gr[j] = x*y;
- break;
- case 4:
- gr[j] = 2 * x * gr[1] - gr[0];
- break;
- case 5:
- gr[j] = 2 * y * gr[2] - gr[0];
- break;
- case 6:
- gr[j] = 2 * x * gr[4] - gr[1];
- break;
- case 7:
- gr[j] = gr[4] * gr[2];
- break;
- case 8:
- gr[j] = gr[5] * gr[1];
- break;
- case 9:
- gr[j] = 2 * y * gr[5] - gr[2];
- break;
- }
- j++;
- }
- }
-
- void calc_m_and_r(data, n_data, model, n_model, grow)
- struct DATA *data;
- int n_data, n_model;
- double *model, *grow;
- {
- /* model[n_model] holds solved coefficients of m_type model.
- grow[n_model] is a vector for a row of G matrix. */
-
- int i, j;
- for (i = 0; i < n_data; i++) {
- load_g_row(data[i].x, data[i].y, n_model, grow);
- data[i].m = 0.0;
- for (j = 0; j < n_model; j++) {
- data[i].m += model[j]*grow[j];
- }
- data[i].r = data[i].z - data[i].m;
- }
- }
-
- void move_model_a_to_b(model_a, model_b, n_model, chisq_a, chisq_b)
- double *model_a, *model_b, *chisq_a, *chisq_b;
- int n_model;
- {
- int i;
- for(i = 0; i< n_model; i++) {
- model_b[i] = model_a[i];
- }
- *chisq_b = *chisq_a;
- }
-
- void load_gtg_and_gtd(data, n_data, gtg, gtd, grow, n_model, mp)
- struct DATA *data;
- double *gtg, *gtd, *grow;
- int n_data, n_model, mp; /* mp is row dimension of gtg */
- {
-
- int i, j, k;
- double wz;
-
- /* First zero the contents for summing: */
-
- for (j = 0; j < n_model; j++) {
- for (k = 0; k < n_model; k++) {
- gtg[j + k*mp] = 0.0;
- }
- gtd[j] = 0.0;
- }
-
- /* Sum over all data */
- for (i = 0; i < n_data; i++) {
- load_g_row(data[i].x, data[i].y, n_model, grow);
- if (data[i].w != 1.0) {
- wz = data[i].w * data[i].z;
- for (j = 0; j < n_model; j++) {
- for (k = 0; k < n_model; k++) {
- gtg[j + k*mp] += (data[i].w * grow[j] * grow[k]);
- }
- gtd[j] += (wz * grow[j]);
- }
- }
- else {
- for (j = 0; j < n_model; j++) {
- for (k = 0; k < n_model; k++) {
- gtg[j + k*mp] += (grow[j] * grow[k]);
- }
- gtd[j] += (data[i].z * grow[j]);
- }
- }
- }
- }
-
- void solve_system(gtg, gtd, model, n_model, mp, lambda, v, b, z, c_no, ir)
- int n_model, mp, *ir;
- double *gtg, *gtd, *model, *lambda, *v, *b, *z, c_no;
-
- {
-
- int i, j, k, rank = 0, n, m, nrots;
- double c_test, temp_inverse_ij;
-
- if (n_model == 1) {
- model[0] = gtd[0] / gtg[0];
- *ir = 1;
- }
- else {
- n = n_model;
- m = mp;
- if(jacobi(gtg, &n, &m, lambda, v, b, z, &nrots)) {
- fprintf(stderr,"trend2d: Warning: Matrix Solver Convergence Failure.\n");
- }
- c_test = fabs(lambda[0])/c_no;
- while(rank < n_model && lambda[rank] > 0.0 && lambda[rank] > c_test) rank++;
- for (i = 0; i < n_model; i++) {
- model[i] = 0.0;
- for (j = 0; j < n_model; j++) {
- temp_inverse_ij = 0.0;
- for (k = 0; k < rank; k++) {
- temp_inverse_ij += (v[i + k*mp] * v[j + k*mp] / lambda[k]);
- }
- model[i] += (temp_inverse_ij * gtd[j]);
- }
- }
- *ir = rank;
- }
- }
-