/*-------------------------------------------------------------------- * $Id: gmtmath_main.c,v 1.4.4.3 2002/02/27 17:58:55 pwessel Exp $ * * Copyright (c) 1991-2002 by P. Wessel and W. H. F. Smith * See COPYING file for copying and redistribution conditions. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Contact info: gmt.soest.hawaii.edu *--------------------------------------------------------------------*/ /* * gmtmath.c is a reverse polish calculator that operates on table files * (and constants) and perform basic mathematical operations * on them like add, multiply, etc. * Some operators only work on one operand (e.g., log, exp) * * Author: Paul Wessel * Date: 10-NOV-1998 * Version: 1.0 based on 3.1 grdmath and sample1d * 3.1.2 PW 03/26/99 Added -H capability * 3.1.2 PW 04/07/99 Added -Q for quick scalar calculator * 3.3.2 PW 09/10/99 Added erfinv * 3.3.3 PW 12/10/99 Added RAND and NRAND * 3.3.4 PW 03/14/00 Fix problems with EXCH and DUP for constants * 3.3.5 PW 07/14/00 Changed STEP to STEPT and added new STEP * 3.3.5 PW 07/31/00 Empty -T means there are no time columns. * 3.3.6 PW 08/16/00 Add LT, LE, EQ, GE, GT, NAN, CHIDIST, FDIST, TDIST * 3.3.6 PW 08/18/00 Add INT, ISNAN, XOR, MODE, MAD, LMSSCL, SUM * 3.3.6 PW 08/18/00 Added -S to just return first row * 3.3.6 PW 08/23/00 Added LOWER and UPPER * 3.4 PW 03/01/01 * 3.4.1 * */ #include "gmt.h" #define N_OPERATORS 93 #define STACK_SIZE 50 #define ARG_IS_FILE 0 #define ARG_IS_NUMBER 1 #define ARG_IS_PI 2 #define ARG_IS_E 3 #define ARG_IS_T_MATRIX 4 #define ARG_IS_OPERATOR 100 #define N_SPECIAL_ARGS 9 #include "gmtmath_def.h" PFV call_operator[N_OPERATORS]; int nm = 0, consumed_operands[N_OPERATORS], produced_operands[N_OPERATORS]; struct GMT_HASH hashnode[HASH_SIZE]; double *t_coordinates; struct TABLE_HEADER { int n_row; /* Number of time-nodes (rows) */ int n_col; /* Number of columns */ double t_min; /* Minimum t value */ double t_max; /* Maximum t value */ double t_inc; /* t increment */ } header; int decode_argument(char *txt), get_operator(char *choice); void gmtmath_init(PFV ops[], int n_args[], int n_out[]); void GMT_read_table (char *file, struct TABLE_HEADER *h, double ***p, int t_col); void GMT_write_table (char *file, struct TABLE_HEADER *h, double **p); void new_table (double ***s, int n_col, int n); void decode_columns (char *txt, int *skip, int n_col, int t_col); BOOLEAN very_first = TRUE; char head_record[BUFSIZ]; char *special_arg[N_SPECIAL_ARGS] = { "PI", "pi", "E", "e", "x", "T", "+", "-", "^" }; main (int argc, char **argv) { int i, j, arg, op = 0, nstack = 0, new_stack = -1, last_arg, ok = 1, type, *skip; int n_col = 2, t_col = 0; BOOLEAN constant[STACK_SIZE], error = FALSE, set_t = FALSE, set_n = FALSE; BOOLEAN one_row_out = FALSE, set_q = FALSE, no_time = FALSE; double **stack[STACK_SIZE]; double factor[STACK_SIZE], t_noise; char *outfile = CNULL, file[BUFSIZ]; struct TABLE_HEADER tbl[STACK_SIZE]; argc = GMT_begin (argc, argv); if (argc == 2 && !strcmp (argv[1], "-")) error = GMT_quick = TRUE; if (argc == 1 || GMT_quick) { fprintf (stderr, "gmtmath %s - Reverse Polish Notation (RPN) calculator for table data\n\n", GMT_VERSION); fprintf (stderr, "usage: gmtmath [-C] [-H[]] [-N/] [-Q] [-S] [-T[]]\n"); fprintf (stderr, "\t[-bi[s][]] [-bo[s][]] [-V] A B op C op ... = [outfile]\n\n"); if (GMT_quick) exit (EXIT_FAILURE); fprintf (stderr, "\tA, B, etc are table files, constants, or symbols (see below)\n"); fprintf (stderr, "\tThe stack can hold up to %d entries (given enough memory)\n", STACK_SIZE); fprintf (stderr, "\tTrigonometric operators expect radians. The operators are:\n\n"); fprintf (stderr, "\tName #args Returns:\n"); fprintf (stderr, "\t-----------------------\n"); #include "gmtmath_explain.h" fprintf (stderr, "\n\tThe special symbols are:\n\n"); fprintf (stderr, "\t PI = 3.1415926...\n"); fprintf (stderr, "\t E = 2.7182818...\n"); fprintf (stderr, "\t T = table with t-coordinates\n"); fprintf (stderr, "\n\tOPTIONS:\n\n"); fprintf (stderr, "\t-C change which columns to operate on [Default is all except time]\n"); fprintf (stderr, "\t -C reverts to the default, -Cr toggles current settings, and -Ca selects all columns.\n"); GMT_explain_option ('H'); fprintf (stderr, "\t-N sets the number of columns and the id of the time column (0 is first) [2/0]\n"); fprintf (stderr, "\t-Q quick scalar calculator. Shorthand for -Ca -N1/0 -T0/0/1\n"); fprintf (stderr, "\t-S Only write first row upon completion of calculations [write all rows]\n"); fprintf (stderr, "\t-T Set domain from t_min to t_max in steps of t_inc\n"); fprintf (stderr, "\t If no domain is given we assume no time, i.e. only data columns are present.\n"); fprintf (stderr, "\t This choice also implies -Ca.\n"); GMT_explain_option ('V'); GMT_explain_option ('i'); GMT_explain_option ('n'); GMT_explain_option ('o'); exit (EXIT_FAILURE); } if (! ((argc > 1 && argv[argc-2][0] == '=') || argv[argc-1][0] == '=')) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Usage is = outfile\n", GMT_program); exit (EXIT_FAILURE); } GMT_put_history (argc, argv); /* Update .gmtcommands */ /* Determine if the user have files with stupid names that will cause conflict */ for (op = 0; op < N_OPERATORS; op++) { if (!access (operator[op], R_OK)) fprintf (stderr, "%s Warning: Your file %s may be confused with a %s operator!\n", GMT_program, operator[op], GMT_program); } for (i = 0; i < N_SPECIAL_ARGS; i++) { if (!access (special_arg[i], R_OK)) fprintf (stderr, "%s Warning: Your file %s may be confused with a %s operator!\n", GMT_program, special_arg[i], GMT_program); } GMT_hash_init (hashnode, operator, HASH_SIZE, N_OPERATORS); for (i = 0; i < STACK_SIZE; i++) { constant[i] = FALSE; factor[i] = 0.0; tbl[i].n_col = tbl[i].n_row = 0; stack[i] = (double **)NULL; } if (!strcmp (argv[argc-2], "=")) { /* Have = file */ outfile = argv[argc-1]; last_arg = argc - 2; } else { outfile = NULL; last_arg = argc - 1; } /* Must first scan command line for -b, -H switches before reading any file */ for (arg = 1; arg < last_arg; arg++) { if (!strncmp (argv[arg], "-b", 2)) error += GMT_io_selection (&argv[arg][2]); if (!strncmp (argv[arg], "-H", 2)) error += GMT_get_common_args (argv[arg], NULL, NULL, NULL, NULL); } /* Get header from one file so we can allocate space */ for (arg = 1; nm == 0 && arg < last_arg; arg++) { if (argv[arg][0] == '-') continue; /* Command line option */ if (decode_argument (argv[arg]) != ARG_IS_FILE) continue; strcpy (file, argv[arg]); GMT_read_table (argv[arg], &header, (double ***)NULL, t_col); nm = header.n_row * header.n_col; n_col = header.n_col; } /* Scan command line for -T, -N, -Q, -S, -V */ for (arg = 1; arg < last_arg; arg++) { if (argv[arg][0] == '-') { switch (argv[arg][1]) { case 'V': error += GMT_get_common_args (argv[arg], NULL, NULL, NULL, NULL); break; case 'N': sscanf (&argv[arg][2], "%d/%d", &n_col, &t_col); set_n = TRUE; break; case 'Q': /* Quick for -Ca -N1/0 -T0/0/1 */ n_col = 1; t_col = 0; set_n = set_t = set_q = TRUE; header.t_min = header.t_max = 0; header.t_inc = 1.0; break; case 'S': one_row_out = TRUE; break; case 'T': i = sscanf (&argv[arg][2], "%lf/%lf/%lf", &header.t_min, &header.t_max, &header.t_inc); if (i == 3) set_t = TRUE; else no_time = TRUE; break; } } } if (GMT_io.binary[0] && gmtdefs.io_header) { fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data cannot have header -H\n", GMT_program); error++; } if (set_n && (n_col <= 0 || t_col < 0 || t_col >= n_col)) { fprintf (stderr, "%s: GMT SYNTAX ERROR: -N must have positive n_cols and 0 <= t_col < n_col\n", GMT_program); exit (EXIT_FAILURE); } if (nm && set_t) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Cannot use -T when data files are specified\n", GMT_program); exit (EXIT_FAILURE); } if (set_t && !set_q) { switch (GMT_minmaxinc_verify (header.t_min, header.t_max, header.t_inc, SMALL)) { case 1: fprintf (stderr, "%s: GMT SYNTAX ERROR -T: (max - min) is not a whole multiple of inc\n", GMT_program); exit (EXIT_FAILURE); break; case 2: fprintf (stderr, "%s: GMT SYNTAX ERROR -T: inc is <= 0\n", GMT_program); exit (EXIT_FAILURE); break; case 3: fprintf (stderr, "%s: GMT SYNTAX ERROR -T: (max - min) is <= 0\n", GMT_program); exit (EXIT_FAILURE); break; default: /* OK */ break; } header.n_row = irint ((header.t_max - header.t_min) / header.t_inc) + 1; header.n_col = n_col; nm = header.n_row * header.n_col; } if (set_q) header.n_row = header.n_col = nm = 1; if (nm == 0) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Expression must contain at least one table file or -T [and -N]\n", GMT_program); exit (EXIT_FAILURE); } new_table (&stack[0], header.n_col, header.n_row); skip = (int *) GMT_memory (VNULL, (size_t)header.n_col, sizeof (int), GMT_program); if (!no_time) skip[t_col] = (set_q) ? FALSE : TRUE; /* Get x and y vectors */ t_coordinates = (double *) GMT_memory (VNULL, (size_t)header.n_row, sizeof (double), GMT_program); for (i = 0; i < header.n_row; i++) t_coordinates[i] = (i == (header.n_row-1)) ? header.t_max: header.t_min + i * header.t_inc; t_noise = fabs (SMALL * header.t_inc); memcpy ((void *)stack[0][t_col], (void *)t_coordinates, (size_t)(header.n_row * sizeof (double))); gmtmath_init (call_operator, consumed_operands, produced_operands); nstack = 0; for (arg = 1; !error && arg < last_arg; arg++) { /* First check if we should skip optional arguments */ if (!(strncmp (argv[arg], "-T", 2) && strncmp (argv[arg], "-b", 2) && strncmp (argv[arg], "-N", 2))) continue; if (!(strncmp (argv[arg], "-H", 2) && strncmp (argv[arg], "-Q", 2) && strncmp (argv[arg], "-S", 2) && strncmp (argv[arg], "-V", 2))) continue; if (!strncmp (argv[arg], "-C", 2)) { /* Change affected columns */ decode_columns (&argv[arg][2], skip, n_col, t_col); continue; } if ((type = decode_argument (argv[arg])) != ARG_IS_OPERATOR) { /* File name or factor */ if (nstack == STACK_SIZE) { /* Stack overflow */ error = TRUE; continue; } if (type == ARG_IS_NUMBER) { constant[nstack] = TRUE; ok = sscanf (argv[arg], "%lf", &factor[nstack]); error = !ok; if (gmtdefs.verbose) fprintf (stderr, "%lg ", factor[nstack]); nstack++; continue; } else if (type == ARG_IS_PI) { constant[nstack] = TRUE; factor[nstack] = M_PI; if (gmtdefs.verbose) fprintf (stderr, "%lg ", factor[nstack]); nstack++; continue; } else if (type == ARG_IS_E) { constant[nstack] = TRUE; factor[nstack] = M_E; if (gmtdefs.verbose) fprintf (stderr, "%lg ", factor[nstack]); nstack++; continue; } /* Here we need a matrix */ if (!stack[nstack]) new_table (&stack[nstack], header.n_col, header.n_row); constant[nstack] = FALSE; if (type == ARG_IS_T_MATRIX) { /* Need to set up matrix of t-values */ if (no_time) { fprintf (stderr, "%s: T is not defined for plain data files!", GMT_program); exit (EXIT_FAILURE); } if (gmtdefs.verbose) fprintf (stderr, "T "); for (j = 0; j < header.n_col; j++) memcpy ((void *)stack[nstack][j], (void *)t_coordinates, (size_t)(header.n_row * sizeof (double))); } else if (type == ARG_IS_FILE) { /* Filename given */ if (gmtdefs.verbose) fprintf (stderr, "%s ", argv[arg]); GMT_read_table (argv[arg], &tbl[nstack], &stack[nstack], t_col); if (tbl[nstack].n_row != header.n_row || tbl[nstack].n_col != header.n_col) { fprintf (stderr, "%s: tables not of same size!\n", GMT_program); exit (EXIT_FAILURE); } else if (!no_time && (fabs (tbl[nstack].t_min - header.t_min) > t_noise || fabs (tbl[nstack].t_max - header.t_max) > t_noise)) { fprintf (stderr, "%s: tables do not cover the same domain!\n", GMT_program); exit (EXIT_FAILURE); } } nstack++; continue; } /* Here we have an operator */ if ((op = get_operator (argv[arg])) < 0) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Unrecognized operator %s\n", GMT_program, argv[arg]); exit (EXIT_FAILURE); } if ((new_stack = nstack - consumed_operands[op] + produced_operands[op]) >= STACK_SIZE) { error = TRUE; continue; } if (nstack < consumed_operands[op]) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Operation \"%s\" requires %d operands\n", GMT_program, operator[op], consumed_operands[op]); exit (EXIT_FAILURE); } if (gmtdefs.verbose) fprintf (stderr, "%s ", operator[op]); for (i = produced_operands[op] - consumed_operands[op]; i > 0; i--) { if (stack[nstack+i-1]) continue; /* Must make space for more */ new_table (&stack[nstack+i-1], header.n_col, header.n_row); } /* If operators operates on constants only we may have to make space as well */ for (j = 0, i = nstack - consumed_operands[op]; j < produced_operands[op]; j++, i++) { if (constant[i] && !stack[i]) new_table (&stack[i], header.n_col, header.n_row); } for (j = 0; j < n_col; j++) { if (skip[j]) continue; (*call_operator[op]) (stack, constant, factor, nstack - 1, j, header.n_row); /* Do it */ } nstack = new_stack; for (i = 1; i <= produced_operands[op]; i++) constant[nstack-i] = FALSE; /* Now filled with table */ } if (error && !ok) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Unable to decode constant %s (File not found?)\n", GMT_program, argv[i-1]); exit (EXIT_FAILURE); } if (error) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Stack overflow (%s)\n", GMT_program, argv[i-1]); exit (EXIT_FAILURE); } if (gmtdefs.verbose) fprintf (stderr, "= %s", outfile); if (new_stack < 0 && constant[0]) { /* Only a constant provided, set grid accordingly */ for (j = 0; j < header.n_col; j++) for (i = 0; i < header.n_row; i++) stack[0][j][i] = factor[0]; } if (one_row_out) header.n_row = 1; /* Trick to get only the first row on output */ GMT_write_table (outfile, &header, stack[0]); for (i = 0; i < STACK_SIZE; i++) if (stack[i]) { for (j = 0; j < header.n_col; j++) GMT_free ((void *)stack[i][j]); GMT_free ((void *)stack[i]); } GMT_free ((void *)t_coordinates); GMT_free ((void *)skip); if (gmtdefs.verbose) fprintf (stderr, "\n"); if (nstack > 1) fprintf (stderr, "%s: Warning: %d more operands left on the stack!\n", GMT_program, nstack-1); GMT_end (argc, argv); } void GMT_read_table (char *file, struct TABLE_HEADER *h, double ***p, int t_col) { int j, n = 0, n_alloc, n_expected_fields, n_fields; double *in, **table; char buffer[BUFSIZ]; FILE *fp; n_expected_fields = (GMT_io.binary[0]) ? GMT_io.ncol[0] : BUFSIZ; #ifdef SET_IO_MODE GMT_setmode (0); #endif if (file && (fp = GMT_fopen (file, GMT_io.r_mode)) == NULL) { fprintf (stderr, "%s: Error opening file %s\n", GMT_program, file); exit (EXIT_FAILURE); } for (j = 0; gmtdefs.io_header && j < gmtdefs.n_header_recs; j++) { GMT_fgets (buffer, BUFSIZ, fp); if (very_first && j == 0) strcpy (head_record, buffer); very_first = FALSE; } GMT_input (fp, &n_expected_fields, &in); if (GMT_io.status & GMT_IO_EOF) { fprintf (stderr, "%s: Error reading 1st record of file %s\n", GMT_program, file); exit (EXIT_FAILURE); } h->n_col = n_expected_fields; n_alloc = GMT_CHUNK; new_table (&table, n_expected_fields, n_alloc); do { for (j = 0; j < h->n_col; j++) table[j][n] = in[j]; n++; if (n == n_alloc) { n_alloc += GMT_CHUNK; for (j = 0; j < h->n_col; j++) table[j] = (double *) GMT_memory ((void *)table[j], (size_t)n_alloc, sizeof (double), GMT_program); } } while ((n_fields = GMT_input (fp, &n_expected_fields, &in)) >= 0 && !(GMT_io.status & GMT_IO_EOF)); h->t_min = table[t_col][0]; h->t_max = table[t_col][n-1]; h->t_inc = (h->t_max - h->t_min) / (n-1); if (p) *p = table; else { /* Discard */ for (j = 0; j < h->n_col; j++) GMT_free ((void *)table[j]); GMT_free ((void *)table); } h->n_row = n; } void GMT_write_table (char *file, struct TABLE_HEADER *h, double **p) { int i, j; double *out; FILE *fp; if (file && (fp = GMT_fopen (file, GMT_io.w_mode)) == NULL) { fprintf (stderr, "%s: Error creating file %s\n", GMT_program, file); exit (EXIT_FAILURE); } else if (!file) fp = GMT_stdout; #ifdef SET_IO_MODE GMT_setmode (1); #endif out = (double *) GMT_memory (VNULL, (size_t)h->n_col, sizeof (double), GMT_program); if (gmtdefs.io_header && !GMT_io.binary[1]) { fprintf (fp, "%s", head_record); for (i = 1; i < gmtdefs.n_header_recs; i++) fprintf (fp, "# gmtmath header record\n"); } for (i = 0; i < h->n_row; i++) { for (j = 0; j < h->n_col; j++) out[j] = p[j][i]; GMT_output (fp, h->n_col, out); } if (fp != GMT_stdout) GMT_fclose (fp); GMT_free ((void *)out); } void new_table (double ***s, int n_col, int n) { int j; double **p; p = (double **) GMT_memory (VNULL, (size_t)n_col, sizeof (double *), GMT_program); for (j = 0; j < n_col; j++) p[j] = (double *) GMT_memory (VNULL, (size_t)n, sizeof (double), GMT_program); *s = p; } void decode_columns (char *txt, int *skip, int n_col, int t_col) { int i, start, stop; char line[BUFSIZ], *p; if (!txt) { /* Reset to default */ for (i = 0; i < n_col; i++) skip[i] = FALSE; skip[t_col] = TRUE; } if (txt[0] == 'r' && txt[1] == '\0') { /* Reverse all settings */ for (i = 0; i < n_col; i++) skip[i] = !skip[i]; } else if (txt[0] == 'a') { /* Select all columns */ for (i = 0; i < n_col; i++) skip[i] = FALSE; } else { /* Set the selected columns */ for (i = 0; i < n_col; i++) skip[i] = TRUE; strcpy (line, txt); p = strtok (line, ","); while (p) { if (strchr (p, '-')) sscanf (p, "%d-%d", &start, &stop); else { sscanf (p, "%d", &start); stop = start; } stop = MIN (stop, n_col-1); for (i = start; i <= stop; i++) skip[i] = FALSE; p = strtok (NULL, ","); } } } /* ----------------------------------------------------------------- * Definitions of all operator functions * -----------------------------------------------------------------*/ void table_ABS (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = fabs (a); } } void table_ACOS (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && fabs (factor[last]) > 1.0) fprintf (stderr, "%s: Warning, |operand| > 1 for ACOS!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = d_acos (a); } } void table_ACOSH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && fabs (factor[last]) > 1.0) fprintf (stderr, "%s: Warning, operand < 1 for ACOSH!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = acosh (a); } } void table_ADD (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = a + b; } } void table_AND (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (GMT_is_dnan (a)) ? b : a; } } void table_ASIN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && fabs (factor[last]) > 1.0) fprintf (stderr, "%s: Warning, |operand| > 1 for ASIN!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = d_asin (a); } } void table_ASINH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = asinh (a); } } void table_ATAN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = atan (a); } } void table_ATAN2 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0 for ATAN2!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0 for ATAN2!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = d_atan2 (a, b); } } void table_ATANH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && fabs (factor[last]) >= 1.0) fprintf (stderr, "%s: Warning, |operand| >= 1 for ATANH!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = atanh (a); } } void table_BEI (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_bei (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_bei (fabs (stack[last][col][i])); } void table_BER (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_ber (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_ber (fabs (stack[last][col][i])); } void table_CEIL (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = ceil (a); } } void table_CHIDIST (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0 for CHIDIST!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0 for CHIDIST!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; GMT_chi2 (a, b, &stack[prev][col][i]); } } void table_COS (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = cos (factor[last]); for (i = 0; i < n_row; i++) { stack[last][col][i] = (constant[last]) ? a : cos (stack[last][col][i]); } } void table_COSD (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = cosd (a); } } void table_COSH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = cosh (a); } } void table_DDT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double c, left, next_left; /* Central 1st difference in t */ if (gmtdefs.verbose && constant[last]) fprintf (stderr, "%s: Warning, operand to DDT is constant!\n", GMT_program); c = 0.5 / header.t_inc; next_left = 2.0 * stack[last][col][0] - stack[last][col][1]; for (i = 0; i < n_row - 1; i++) { left = next_left; next_left = stack[last][col][i]; stack[last][col][i] = (constant[last]) ? 0.0 : c * (stack[last][col][i+1] - left); } stack[last][col][i] = (constant[last]) ? 0.0 : 2.0 * c * (stack[last][col][i] - next_left); } void table_D2DT2 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double c, left, next_left; /* Central 2nd difference in t */ if (gmtdefs.verbose && constant[last]) fprintf (stderr, "%s: Warning, operand to D2DT2 is constant!\n", GMT_program); c = 1.0 / (header.t_inc * header.t_inc); next_left = stack[last][col][0]; stack[last][col][0] = 0.0; for (i = 1; i < n_row - 1; i++) { left = next_left; next_left = stack[last][col][i]; stack[last][col][i] = (constant[last]) ? 0.0 : c * (stack[last][col][i+1] - 2 * stack[last][col][i] + left); } stack[last][col][i] = 0.0; } void table_D2R (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = a * D2R; } } void table_DILOG (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_dilog (factor[last]); for (i = 0; i < n_row; i++) { stack[last][col][i] = (constant[last]) ? a : GMT_dilog (stack[last][col][i]); } } void table_DIV (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (constant[last] && factor[last] == 0.0) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Cannot divide by zero\n", GMT_program); exit (EXIT_FAILURE); } if (constant[last]) { /* Turn divide into multiply */ factor[last] = 1.0 / factor[last]; table_MUL (stack, constant, factor, last, col, n_row); return; } for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = a / b; } } void table_DUP (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int next, i; next = last + 1; factor[next] = factor[last]; constant[next] = constant[last]; if (constant[last]) for (i = 0; i < n_row; i++) stack[next][col][i] = stack[last][col][i] = factor[next]; else memcpy ((void *)stack[next][col], (void *)stack[last][col], (size_t)(n_row * sizeof (double))); } void table_ERF (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = erf (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : erf (stack[last][col][i]); } void table_ERFC (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = erfc (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : erfc (stack[last][col][i]); } void table_ERFINV (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_erfinv (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_erfinv (stack[last][col][i]); } void table_EQ (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (double)(a == b); } } void table_EXCH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; prev = last - 1; for (i = 0; i < n_row; i++) { if (constant[last]) stack[last][col][i] = factor[last]; if (constant[prev]) stack[prev][col][i] = factor[prev]; d_swap (stack[last][col][i], stack[prev][col][i]); } i_swap (constant[last], constant[prev]); d_swap (factor[last], factor[prev]); } void table_EXP (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = exp (a); } } void table_FDIST (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, c, d, prev1, prev2, prev3; double a, b; prev1 = last - 1; prev2 = last - 2; prev3 = last - 3; if (gmtdefs.verbose && constant[prev3] && factor[prev3] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0 for FDIST!\n", GMT_program); if (gmtdefs.verbose && constant[prev2] && factor[prev2] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0 for FDIST!\n", GMT_program); if (gmtdefs.verbose && constant[prev1] && factor[prev1] == 0.0) fprintf (stderr, "%s: Warning, operand three == 0 for FDIST!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand four == 0 for FDIST!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev3]) ? factor[prev3] : stack[prev3][col][i]; b = (constant[prev2]) ? factor[prev2] : stack[prev2][col][i]; c = irint ((double)((constant[prev1]) ? factor[prev1] : stack[prev1][col][i])); d = irint ((double)((constant[last]) ? factor[last] : stack[last][col][i])); (void) GMT_f_q (a * c, c, b * d, d, &stack[prev3][col][i]); } } void table_FLOOR (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = floor (a); } } void table_FMOD (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = fmod (a, b); } } void table_GE (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (double)(a >= b); } } void table_GT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (double)(a > b); } } void table_HYPOT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = hypot (a, b); } } void table_I0 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_i0 (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_i0 (stack[last][col][i]); } void table_I1 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_i1 (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_i1 (stack[last][col][i]); } void table_IN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev, order; BOOLEAN simple = FALSE; double b; prev = last - 1; if (gmtdefs.verbose && constant[last] && factor[last] < 0.0) fprintf (stderr, "%s: Warning, order < 0 for IN!\n", GMT_program); if (gmtdefs.verbose && constant[last] && fabs (rint(factor[last]) - factor[last]) > SMALL) fprintf (stderr, "%s: Warning, order not an integer for IN!\n", GMT_program); if (constant[last]) order = irint (fabs (factor[last])); if (constant[last] && constant[prev]) { b = GMT_in (order, fabs (factor[prev])); simple = TRUE; } for (i = 0; i < n_row; i++) { if (simple) stack[prev][col][i] = b; else { if (!constant[last]) order = irint (fabs (stack[last][col][i])); stack[prev][col][i] = GMT_in (order, fabs (stack[prev][col][i])); } } } void table_INT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double f, left, right, sum; if (constant[last]) { /* Trivial case */ sum = factor[last] * header.t_inc; for (i = 0; i < n_row; i++) stack[last][col][i] = i * sum; return; } left = stack[last][col][0]; stack[last][col][0] = sum = 0.0; f = 0.5 * header.t_inc; for (i = 1; i < n_row; i++) { /* Dumb trapezoidal rule */ right = stack[last][col][i]; sum += f * (left + right); stack[last][col][i] = sum; left = right; } } void table_INV (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last] && factor[last] == 0.0) { fprintf (stderr, "%s: Error, Cannot take inverse of zero!\n", GMT_program); exit (EXIT_FAILURE); } if (constant[last]) factor[last] = 1.0 / factor[last]; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : 1.0 / stack[last][col][i]; stack[last][col][i] = a; } } void table_ISNAN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = factor[last]; for (i = 0; i < n_row; i++) { if (!constant[last]) a = stack[last][col][i]; stack[last][col][i] = (double)GMT_is_dnan (a); } } void table_J0 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = j0 (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : j0 (stack[last][col][i]); } void table_J1 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = j1 (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : j1 (fabs (stack[last][col][i])); } void table_JN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev, order; BOOLEAN simple = FALSE; double b; prev = last - 1; if (gmtdefs.verbose && constant[last] && factor[last] < 0.0) fprintf (stderr, "%s: Warning, order < 0 for JN!\n", GMT_program); if (gmtdefs.verbose && constant[last] && fabs (rint(factor[last]) - factor[last]) > SMALL) fprintf (stderr, "%s: Warning, order not an integer for JN!\n", GMT_program); if (constant[last]) order = irint (fabs (factor[last])); if (constant[last] && constant[prev]) { b = jn (order, fabs (factor[prev])); simple = TRUE; } for (i = 0; i < n_row; i++) { if (simple) stack[prev][col][i] = b; else { if (!constant[last]) order = irint (fabs (stack[last][col][i])); stack[prev][col][i] = jn (order, fabs (stack[prev][col][i])); } } } void table_K0 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_k0 (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_k0 (stack[last][col][i]); } void table_K1 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_k1 (factor[last]); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_k1 (stack[last][col][i]); } void table_KN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev, order; BOOLEAN simple = FALSE; double b; prev = last - 1; if (gmtdefs.verbose && constant[last] && factor[last] < 0.0) fprintf (stderr, "%s: Warning, order < 0 for KN!\n", GMT_program); if (gmtdefs.verbose && constant[last] && fabs (rint(factor[last]) - factor[last]) > SMALL) fprintf (stderr, "%s: Warning, order not an integer for KN!\n", GMT_program); if (constant[last]) order = irint (fabs (factor[last])); if (constant[last] && constant[prev]) { b = GMT_kn (order, fabs (factor[prev])); simple = TRUE; } for (i = 0; i < n_row; i++) { if (simple) stack[prev][col][i] = b; else { if (!constant[last]) order = irint (fabs (stack[last][col][i])); stack[prev][col][i] = GMT_kn (order, fabs (stack[prev][col][i])); } } } void table_KEI (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_kei (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_kei (fabs (stack[last][col][i])); } void table_KER (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (constant[last]) a = GMT_ker (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : GMT_ker (fabs (stack[last][col][i])); } void table_LE (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (double)(a <= b); } } void table_LMSSCL (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double lmsscl, mode; if (constant[last]) { /* Trivial case */ memset ((void *)stack[last][col], 0, (size_t)(n_row * sizeof (double))); return; } qsort ((void *)stack[last][col], (size_t)n_row, sizeof (double), GMT_comp_double_asc); for (i = n_row; GMT_is_fnan (stack[last][col][i-1]) && i > 1; i--); if (i) { GMT_mode (stack[last][col], i, i/2, 0, &mode); GMT_getmad (stack[last][col], i, mode, &lmsscl); } else lmsscl = GMT_d_NaN; for (i = 0; i < n_row; i++) stack[last][col][i] = lmsscl; } void table_LOG (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, argument to log = 0!\n", GMT_program); if (constant[last]) a = d_log (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : d_log (fabs (stack[last][col][i])); } void table_LOG10 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, argument to log10 = 0!\n", GMT_program); if (constant[last]) a = d_log10 (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : d_log10 (fabs (stack[last][col][i])); } void table_LOG1P (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] < 0.0) fprintf (stderr, "%s: Warning, argument to log1p < 0!\n", GMT_program); if (constant[last]) a = d_log1p (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : d_log1p (fabs (stack[last][col][i])); } void table_LOWER (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double low; if (constant[last]) { /* Trivial case */ for (i = 0; i < n_row; i++) stack[last][col][i] = factor[last]; return; } for (i = 0, low = DBL_MAX; i < n_row; i++) { if (GMT_is_fnan (stack[last][col][i])) continue; if (stack[last][col][i] < low) low = stack[last][col][i]; } for (i = 0; i < n_row; i++) if (!GMT_is_fnan (stack[last][col][i])) stack[last][col][i] = low; } void table_LT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (double)(a < b); } } void table_MAD (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double mad, med; if (constant[last]) { /* Trivial case */ memset ((void *)stack[last][col], 0, (size_t)(n_row * sizeof (double))); return; } qsort ((void *)stack[last][col], (size_t)n_row, sizeof (double), GMT_comp_double_asc); for (i = n_row; GMT_is_fnan (stack[last][col][i-1]) && i > 1; i--); if (i) { med = (i%2) ? stack[last][col][i/2] : 0.5 * (stack[last][col][(i-1)/2] + stack[last][col][i/2]); GMT_getmad (stack[last][col], i, med, &mad); } else mad = GMT_d_NaN; for (i = 0; i < n_row; i++) stack[last][col][i] = mad; } void table_MAX (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = MAX (a, b); } } void table_MEAN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, n_a = 0; double sum_a = 0.0; if (constant[last]) { /* Trivial case */ for (i = 0; i < n_row; i++) stack[last][col][i] = factor[last]; return; } for (i = 0; i < n_row; i++) { if (GMT_is_fnan (stack[last][col][i])) continue; sum_a += stack[last][col][i]; n_a++; } sum_a = (n_a) ? sum_a / n_a : 0.0; for (i = 0; i < n_row; i++) stack[last][col][i] = sum_a; } void table_MED (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double med; if (constant[last]) { /* Trivial case */ for (i = 0; i < n_row; i++) stack[last][col][i] = factor[last]; return; } qsort ((void *)stack[last][col], (size_t)n_row, sizeof (double), GMT_comp_double_asc); for (i = n_row; GMT_is_fnan (stack[last][col][i-1]) && i > 1; i--); if (i) med = (i%2) ? stack[last][col][i/2] : 0.5 * (stack[last][col][(i-1)/2] + stack[last][col][i/2]); else med = GMT_d_NaN; for (i = 0; i < n_row; i++) stack[last][col][i] = med; } void table_MIN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = MIN (a, b); } } void table_MODE (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double mode; if (constant[last]) { /* Trivial case */ for (i = 0; i < n_row; i++) stack[last][col][i] = factor[last]; return; } qsort ((void *)stack[last][col], (size_t)n_row, sizeof (double), GMT_comp_double_asc); for (i = n_row; GMT_is_fnan (stack[last][col][i-1]) && i > 1; i--); if (i) GMT_mode (stack[last][col], i, i/2, 0, &mode); else mode = GMT_d_NaN; for (i = 0; i < n_row; i++) stack[last][col][i] = mode; } void table_MUL (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = a * b; } } void table_NAN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (constant[prev]) a = factor[prev]; if (constant[last]) b = factor[last]; for (i = 0; i < n_row; i++) { if (!constant[prev]) a = stack[prev][col][i]; if (!constant[last]) b = stack[last][col][i]; stack[prev][col][i] = ((a == b) ? GMT_d_NaN : a); } } void table_NEG (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = -a; } } void table_NRAND (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (constant[prev]) a = factor[prev]; if (constant[last]) b = factor[last]; for (i = 0; i < n_row; i++) { if (!constant[prev]) a = stack[prev][col][i]; if (!constant[last]) b = stack[last][col][i]; stack[prev][col][i] = a + b * GMT_nrand (); } } void table_OR (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = (GMT_is_dnan (a) || GMT_is_dnan (b)) ? GMT_d_NaN : a; } } void table_PLM (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev, first, L, M; double a; /* last holds the order M */ prev = last - 1; /* prev holds the degree L */ first = prev - 1; /* first holds the argument x = cos(colat) */ if (!(constant[prev] && constant[last])) { fprintf (stderr, "%s: L and M must be constants in PLM!\n", GMT_program); exit (EXIT_FAILURE); } L = irint (factor[prev]); M = irint (factor[last]); if (gmtdefs.verbose && constant[first] && (factor[first] < -1.0 || factor[first] > 1.0)) fprintf (stderr, "%s: Warning, argument to PLM outside domain!\n", GMT_program); if (constant[first]) a = GMT_plm (L, M, factor[first]); for (i = 0; i < n_row; i++) stack[first][col][i] = (constant[first]) ? a : GMT_plm (L, M, stack[first][col][i]); } void table_POP (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { /* Dummy rutine that does nothing but consume the top element of stack */ } void table_POW (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = pow (a, b); } } void table_R2 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); if (constant[prev]) factor[prev] *= factor[prev]; if (constant[last]) factor[last] *= factor[last]; for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i] * stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i] * stack[last][col][i]; stack[prev][col][i] = a + b; } } void table_R2D (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = a * R2D; } } void table_RAND (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (constant[prev]) a = factor[prev]; if (constant[last]) b = factor[last]; for (i = 0; i < n_row; i++) { if (!constant[prev]) a = stack[prev][col][i]; if (!constant[last]) b = stack[last][col][i]; stack[prev][col][i] = a + GMT_rand () * (b - a); } } void table_RINT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = rint (a); } } void table_SIGN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = copysign (1.0, a); } } void table_SIN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = sin (a); } } void table_SIND (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = sind (a); } } void table_SINH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = sinh (a); } } void table_SQRT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = sqrt (a); } } void table_STD (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, n_a = 0; double sum_a = 0.0, sum_a2 = 0.0, std; if (constant[last]) { /* Trivial case */ memset ((void *)stack[last][col], 0, (size_t)(n_row * sizeof (double))); return; } for (i = 0; i < n_row; i++) { if (GMT_is_fnan (stack[last][col][i])) continue; sum_a += stack[last][col][i]; sum_a2 += (stack[last][col][i] * stack[last][col][i]); n_a++; } if (n_a > 1) std = sqrt ((n_a * sum_a2 - sum_a * sum_a) / (n_a * (n_a - 1.0))); else std = 0.0; for (i = 0; i < n_row; i++) stack[last][col][i] = std; } void table_STEP (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; if (a == 0.0) stack[last][col][i] = 0.5; else stack[last][col][i] = (a < 0.0) ? 0.0 : 1.0; } } void table_STEPT (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = t_coordinates[i] - ((constant[last]) ? factor[last] : stack[last][col][i]); if (a == 0.0) stack[last][col][i] = 0.5; else stack[last][col][i] = (a < 0.0) ? 0.0 : 1.0; } } void table_SUB (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = (constant[last]) ? factor[last] : stack[last][col][i]; stack[prev][col][i] = a - b; } } void table_SUM (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a, sum = 0.0; if (constant[last]) a = factor[last]; for (i = 0; i < n_row; i++) { if (!constant[last]) a = stack[last][col][i]; if (!GMT_is_dnan (a)) sum += a; stack[last][col][i] = sum; } } void table_TAN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = tan (a); } } void table_TAND (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = tand (a); } } void table_TANH (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; for (i = 0; i < n_row; i++) { a = (constant[last]) ? factor[last] : stack[last][col][i]; stack[last][col][i] = tanh (a); } } void table_TDIST (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, b, prev; double a; prev = last - 1; if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, operand one == 0 for TDIST!\n", GMT_program); if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand two == 0 for TDIST!\n", GMT_program); for (i = 0; i < n_row; i++) { a = (constant[prev]) ? factor[prev] : stack[prev][col][i]; b = irint ((constant[last]) ? factor[last] : stack[last][col][i]); (void) GMT_student_t_a (a, b, &stack[prev][col][i]); } } void table_UPPER (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double high; if (constant[last]) { /* Trivial case */ for (i = 0; i < n_row; i++) stack[last][col][i] = factor[last]; return; } for (i = 0, high = -DBL_MAX; i < n_row; i++) { if (GMT_is_fnan (stack[last][col][i])) continue; if (stack[last][col][i] > high) high = stack[last][col][i]; } for (i = 0; i < n_row; i++) if (!GMT_is_fnan (stack[last][col][i])) stack[last][col][i] = high; } void table_XOR (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev; double a, b; prev = last - 1; if (constant[prev]) a = factor[prev]; if (constant[last]) b = factor[last]; for (i = 0; i < n_row; i++) { if (!constant[prev]) a = stack[prev][col][i]; if (!constant[last]) b = stack[last][col][i]; stack[prev][col][i] = (GMT_is_dnan (a)) ? b : a; } } void table_Y0 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand = 0 for Y0!\n", GMT_program); if (constant[last]) a = y0 (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : y0 (fabs (stack[last][col][i])); } void table_Y1 (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i; double a; if (gmtdefs.verbose && constant[last] && factor[last] == 0.0) fprintf (stderr, "%s: Warning, operand = 0 for Y1!\n", GMT_program); if (constant[last]) a = y1 (fabs (factor[last])); for (i = 0; i < n_row; i++) stack[last][col][i] = (constant[last]) ? a : y1 (fabs (stack[last][col][i])); } void table_YN (double **stack[], BOOLEAN *constant, double *factor, int last, int col, int n_row) { int i, prev, order; BOOLEAN simple = FALSE; double b; prev = last - 1; if (gmtdefs.verbose && constant[last] && factor[last] < 0.0) fprintf (stderr, "%s: Warning, order < 0 for YN!\n", GMT_program); if (gmtdefs.verbose && constant[last] && fabs (rint(factor[last]) - factor[last]) > SMALL) fprintf (stderr, "%s: Warning, order not an integer for YN!\n", GMT_program); if (gmtdefs.verbose && constant[prev] && factor[prev] == 0.0) fprintf (stderr, "%s: Warning, argument = 0 for YN!\n", GMT_program); if (constant[last]) order = irint (fabs (factor[last])); if (constant[last] && constant[prev]) { b = yn (order, fabs (factor[prev])); simple = TRUE; } for (i = 0; i < n_row; i++) { if (simple) stack[prev][col][i] = b; else { if (!constant[last]) order = irint (fabs (stack[last][col][i])); stack[prev][col][i] = yn (order, fabs (stack[prev][col][i])); } } } /* ---------------------- end operator functions --------------------- */ int decode_argument (txt) char *txt; { int number, minus, plus, exp, dec, n_digits = 0; char *s; if (!strcmp (txt, "/")) return ARG_IS_OPERATOR; /* Special test since / is also a directory */ /* First see if argument it can be opened as a file */ if (!access (txt, R_OK)) return ARG_IS_FILE; /* returns FALSE if file exists and can be read */ /* Next look for symbols with special meaning */ if (!(strcmp (txt, "PI") && strcmp (txt, "pi"))) return ARG_IS_PI; if (!(strcmp (txt, "E") && strcmp (txt, "e"))) return ARG_IS_E; if (!(strcmp (txt, "T") && strcmp (txt, "t"))) return ARG_IS_T_MATRIX; /* Here we must check if argument is a numerical value */ s = txt; if (*s == '-' || *s == '+') s++; /* Skip leading sign */ minus = plus = exp = dec = 0; number = TRUE; while (number && *s) { if (isdigit ((int)*s)) n_digits++; else { switch (*s) { case '-': minus++; break; case '+': plus++; break; case 'E': case 'e': exp++; break; case '.': dec++; break; default: number = FALSE; break; } } if (minus > 1 || exp > 1 || dec > 1) number = FALSE; s++; } if (txt[0] == '-' && !number) { /* Probably a bad commandline option */ fprintf (stderr, "%s: ERROR: Option %s not recognized\n", GMT_program, txt); exit (EXIT_FAILURE); } return ((number && n_digits > 0) ? ARG_IS_NUMBER : ARG_IS_OPERATOR); } int get_operator (choice) char *choice; { int op; /* Returns -1 if not a registered operator */ op = GMT_hash_lookup (choice, hashnode, HASH_SIZE); if (op < 0 && strlen (choice) == 1) { /* Check for old-style operators */ switch (choice[0]) { case '+': op = ADD; break; case '-': op = SUB; break; case 'x': op = MUL; break; case '/': op = DIV; break; case '^': op = RAISE; break; } } return (op); } void gmtmath_init (PFV ops[], int n_args[], int n_out[]) { /* Operator function # of operands # of outputs */ ops[0] = table_ABS; n_args[0] = 1; n_out[0] = 1; ops[1] = table_ACOS; n_args[1] = 1; n_out[1] = 1; ops[2] = table_ACOSH; n_args[2] = 1; n_out[2] = 1; ops[3] = table_ADD; n_args[3] = 2; n_out[3] = 1; ops[4] = table_AND; n_args[4] = 2; n_out[4] = 1; ops[5] = table_ASIN; n_args[5] = 1; n_out[5] = 1; ops[6] = table_ASINH; n_args[6] = 1; n_out[6] = 1; ops[7] = table_ATAN; n_args[7] = 1; n_out[7] = 1; ops[8] = table_ATAN2; n_args[8] = 2; n_out[8] = 1; ops[9] = table_ATANH; n_args[9] = 1; n_out[9] = 1; ops[10] = table_BEI; n_args[10] = 1; n_out[10] = 1; ops[11] = table_BER; n_args[11] = 1; n_out[11] = 1; ops[12] = table_CEIL; n_args[12] = 1; n_out[12] = 1; ops[13] = table_CHIDIST; n_args[13] = 2; n_out[13] = 1; ops[14] = table_COS; n_args[14] = 1; n_out[14] = 1; ops[15] = table_COSD; n_args[15] = 1; n_out[15] = 1; ops[16] = table_COSH; n_args[16] = 1; n_out[16] = 1; ops[17] = table_D2DT2; n_args[17] = 1; n_out[17] = 1; ops[18] = table_D2R; n_args[18] = 1; n_out[18] = 1; ops[19] = table_DILOG; n_args[19] = 1; n_out[19] = 1; ops[20] = table_DIV; n_args[20] = 2; n_out[20] = 1; ops[21] = table_DDT; n_args[21] = 1; n_out[21] = 1; ops[22] = table_DUP; n_args[22] = 1; n_out[22] = 2; ops[23] = table_ERF; n_args[23] = 1; n_out[23] = 1; ops[24] = table_ERFC; n_args[24] = 1; n_out[24] = 1; ops[25] = table_ERFINV; n_args[25] = 1; n_out[25] = 1; ops[26] = table_EQ; n_args[26] = 2; n_out[26] = 1; ops[27] = table_EXCH; n_args[27] = 2; n_out[27] = 2; ops[28] = table_EXP; n_args[28] = 1; n_out[28] = 1; ops[29] = table_FDIST; n_args[29] = 4; n_out[29] = 1; ops[30] = table_FLOOR; n_args[30] = 1; n_out[30] = 1; ops[31] = table_FMOD; n_args[31] = 2; n_out[31] = 1; ops[32] = table_GE; n_args[32] = 2; n_out[32] = 1; ops[33] = table_GT; n_args[33] = 2; n_out[33] = 1; ops[34] = table_HYPOT; n_args[34] = 2; n_out[34] = 1; ops[35] = table_I0; n_args[35] = 1; n_out[35] = 1; ops[36] = table_I1; n_args[36] = 1; n_out[36] = 1; ops[37] = table_IN; n_args[37] = 2; n_out[37] = 1; ops[38] = table_INT; n_args[38] = 1; n_out[38] = 1; ops[39] = table_INV; n_args[39] = 1; n_out[39] = 1; ops[40] = table_ISNAN; n_args[40] = 1; n_out[40] = 1; ops[41] = table_J0; n_args[41] = 1; n_out[41] = 1; ops[42] = table_J1; n_args[42] = 1; n_out[42] = 1; ops[43] = table_JN; n_args[43] = 2; n_out[43] = 1; ops[44] = table_K0; n_args[44] = 1; n_out[44] = 1; ops[45] = table_K1; n_args[45] = 1; n_out[45] = 1; ops[46] = table_KN; n_args[46] = 2; n_out[46] = 1; ops[47] = table_KEI; n_args[47] = 1; n_out[47] = 1; ops[48] = table_KER; n_args[48] = 1; n_out[48] = 1; ops[49] = table_LE; n_args[49] = 2; n_out[49] = 1; ops[50] = table_LMSSCL; n_args[50] = 1; n_out[50] = 1; ops[51] = table_LOG; n_args[51] = 1; n_out[51] = 1; ops[52] = table_LOG10; n_args[52] = 1; n_out[52] = 1; ops[53] = table_LOG1P; n_args[53] = 1; n_out[53] = 1; ops[54] = table_LOWER; n_args[54] = 1; n_out[54] = 1; ops[55] = table_LT; n_args[55] = 2; n_out[55] = 1; ops[56] = table_MAD; n_args[56] = 1; n_out[56] = 1; ops[57] = table_MAX; n_args[57] = 2; n_out[57] = 1; ops[58] = table_MEAN; n_args[58] = 1; n_out[58] = 1; ops[59] = table_MED; n_args[59] = 1; n_out[59] = 1; ops[60] = table_MIN; n_args[60] = 2; n_out[60] = 1; ops[61] = table_MODE; n_args[61] = 1; n_out[61] = 1; ops[62] = table_MUL; n_args[62] = 2; n_out[62] = 1; ops[63] = table_NAN; n_args[63] = 2; n_out[63] = 1; ops[64] = table_NEG; n_args[64] = 1; n_out[64] = 1; ops[65] = table_NRAND; n_args[65] = 2; n_out[65] = 1; ops[66] = table_OR; n_args[66] = 2; n_out[66] = 1; ops[67] = table_PLM; n_args[67] = 3; n_out[67] = 1; ops[68] = table_POP; n_args[68] = 1; n_out[68] = 0; ops[69] = table_POW; n_args[69] = 2; n_out[69] = 1; ops[70] = table_R2; n_args[70] = 2; n_out[70] = 1; ops[71] = table_R2D; n_args[71] = 1; n_out[71] = 1; ops[72] = table_RAND; n_args[72] = 2; n_out[72] = 1; ops[73] = table_RINT; n_args[73] = 1; n_out[73] = 1; ops[74] = table_SIGN; n_args[74] = 1; n_out[74] = 1; ops[75] = table_SIN; n_args[75] = 1; n_out[75] = 1; ops[76] = table_SIND; n_args[76] = 1; n_out[76] = 1; ops[77] = table_SINH; n_args[77] = 1; n_out[77] = 1; ops[78] = table_SQRT; n_args[78] = 1; n_out[78] = 1; ops[79] = table_STD; n_args[79] = 1; n_out[79] = 1; ops[80] = table_STEP; n_args[80] = 1; n_out[80] = 1; ops[81] = table_STEPT; n_args[81] = 1; n_out[81] = 1; ops[82] = table_SUB; n_args[82] = 2; n_out[82] = 1; ops[83] = table_SUM; n_args[83] = 1; n_out[83] = 1; ops[84] = table_TAN; n_args[84] = 1; n_out[84] = 1; ops[85] = table_TAND; n_args[85] = 1; n_out[85] = 1; ops[86] = table_TANH; n_args[86] = 1; n_out[86] = 1; ops[87] = table_TDIST; n_args[87] = 2; n_out[87] = 1; ops[88] = table_UPPER; n_args[88] = 1; n_out[88] = 1; ops[89] = table_XOR; n_args[89] = 2; n_out[89] = 1; ops[90] = table_Y0; n_args[90] = 1; n_out[90] = 1; ops[91] = table_Y1; n_args[91] = 1; n_out[91] = 1; ops[92] = table_YN; n_args[92] = 2; n_out[92] = 1; }