123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905 |
- #include "sys-defines.h"
- #include "libcommon.h"
- #include "getopt.h"
- enum { STATE_ZERO, STATE_ONE, STATE_TWO, STATE_THREE };
- enum { AUTO_NONE, AUTO_INCREMENT, AUTO_BY_DISTANCE };
- #define FUZZ 0.0000001
- #define TRIG_ARG_MIN 0.001
- #define TRIG_ARG_MAX 50.0
- #define ARG_NONE 0
- #define ARG_REQUIRED 1
- #define ARG_OPTIONAL 2
- const char *optstring = "fpsAd:I:O:P:k:n:t:x:T:a::";
- struct option long_options[] =
- {
- {"no-of-intervals", ARG_REQUIRED, NULL, 'n'},
- {"periodic", ARG_NONE, NULL, 'p'},
- {"y-dimension", ARG_REQUIRED, NULL, 'd'},
- {"t-limits", ARG_REQUIRED, NULL, 't'},
- {"t-limits", ARG_REQUIRED, NULL, 'x'},
- {"tension", ARG_REQUIRED, NULL, 'T'},
- {"boundary-condition",ARG_REQUIRED, NULL, 'k'},
- {"auto-abscissa", ARG_OPTIONAL, NULL, 'a'},
- {"auto-dist-abscissa",ARG_NONE, NULL, 'A'},
- {"filter", ARG_NONE, NULL, 'f'},
- {"precision", ARG_REQUIRED, NULL, 'P'},
- {"suppress-abscissa", ARG_NONE, NULL, 's'},
-
- {"input-type", ARG_REQUIRED, NULL, 'I'},
- {"output-type", ARG_REQUIRED, NULL, 'O'},
-
- {"version", ARG_NONE, NULL, 'V' << 8},
- {"help", ARG_NONE, NULL, 'h' << 8},
- {NULL, 0, 0, 0}
- };
- const int hidden_options[] = { (int)'x', 0 };
- typedef enum
- {
- T_ASCII, T_SINGLE, T_DOUBLE, T_INTEGER
- }
- data_type;
- data_type input_type = T_ASCII;
- data_type output_type = T_ASCII;
- const char *progname = "spline";
- const char *written = "Written by Robert S. Maier and Rich Murphey.";
- const char *copyright = "Copyright (C) 2009 Free Software Foundation, Inc.";
- const char *usage_appendage = " [FILE]...\n\
- With no FILE, or when FILE is -, read standard input.\n";
- bool do_bessel (FILE *input, int ydimension, int auto_abscissa, double auto_t, double auto_delta, double first_t, double last_t, double spacing_t, int precision, bool suppress_abscissa);
- bool is_monotonic (int n, double *t);
- bool read_data (FILE *input, int *len, int *used, int auto_abscissa, double auto_t, double auto_delta, double **t, int ydimension, double **y, double **z);
- bool read_float (FILE *input, double *dptr);
- bool skip_whitespace (FILE *stream);
- bool write_point (double t, double *y, int ydimension, int precision, bool suppress_abscissa);
- double interpolate (int n, double *t, double *y, double *z, double x, double tension, bool periodic);
- double quotient_sin_func (double x, double y);
- double quotient_sinh_func (double x, double y);
- double sin_func (double x);
- double sinh_func (double x);
- double tan_func (double x);
- double tanh_func (double x);
- int read_point (FILE *input, double *t, double *y, int ydimension, bool *first_point, int auto_abscissa, double *auto_t, double auto_delta, double *stored);
- void do_bessel_range (double abscissa0, double abscissa1, double *value0, double *value1, double *slope0, double *slope1, double first_t, double last_t, double spacing_t, int ydimension, int precision, bool endit, bool suppress_abscissa);
- void do_spline (int used, int len, double **t, int ydimension, double **y, double **z, double tension, bool periodic, bool spec_boundary_condition, double boundary_condition, int precision, double first_t, double last_t, double spacing_t, int no_of_intervals, bool spec_first_t, bool spec_last_t, bool spec_spacing_t, bool spec_no_of_intervals, bool suppress_abscissa);
- void fit (int n, double *t, double *y, double *z, double k, double tension, bool periodic);
- void maybe_emit_oob_warning (void);
- void non_monotonic_error (void);
- void output_dataset_separator (void);
- void set_format_type (char *s, data_type *typep);
- int
- main (int argc, char *argv[])
- {
- int option;
- int opt_index;
- int errcnt = 0;
- bool show_version = false;
- bool show_usage = false;
- bool dataset_follows;
-
- bool filter = false;
- bool periodic = false;
- bool spec_boundary_condition = false;
- bool spec_first_t = false, spec_last_t = false, spec_spacing_t = false;
- bool spec_no_of_intervals = false;
- bool suppress_abscissa = false;
- double boundary_condition = 1.0;
- double delta_t = 1.0;
- double first_t = 0.0, last_t = 0.0, spacing_t = 0.0;
- double tension = 0.0;
- double t_start = 0.0;
- int auto_abscissa = AUTO_NONE;
- int no_of_intervals = 100;
- int precision = 6;
- int ydimension = 1;
-
- double local_first_t, local_last_t, local_spacing_t;
- double local_t_start, local_delta_t;
- int local_precision;
- for ( ; ; )
- {
- option = getopt_long (argc, argv, optstring, long_options, &opt_index);
- if (option == 0)
- option = long_options[opt_index].val;
-
- switch (option)
- {
-
- case 'p':
- periodic = true;
- break;
- case 'f':
- filter = true;
- break;
- case 's':
- suppress_abscissa = true;
- break;
- case 'A':
- auto_abscissa = AUTO_BY_DISTANCE;
- t_start = 0.0;
- break;
- case 'V' << 8:
- show_version = true;
- break;
- case 'h' << 8:
- show_usage = true;
- break;
-
- case 'I':
- set_format_type (optarg, &input_type);
- break;
- case 'O':
- set_format_type (optarg, &output_type);
- break;
- case 'd':
- if (sscanf (optarg, "%d", &ydimension) <= 0 || ydimension < 1)
- {
- fprintf (stderr,
- "%s: error: the ordinate dimension `%s' is bad (it should be a positive integer)\n",
- progname, optarg);
- errcnt++;
- }
- break;
- case 'k':
- if (sscanf (optarg, "%lf", &boundary_condition) <= 0)
- {
- fprintf (stderr,
- "%s: error: the boundary condition argument `%s' is bad\n",
- progname, optarg);
- errcnt++;
- }
- else
- spec_boundary_condition = true;
- break;
- case 'T':
- if (sscanf (optarg, "%lf", &tension) <= 0)
- {
- fprintf (stderr,
- "%s: error: the tension argument `%s' is bad\n",
- progname, optarg);
- errcnt++;
- }
- break;
- case 'n':
- if (sscanf (optarg, "%d", &no_of_intervals) <= 0)
- {
- fprintf (stderr,
- "%s: error: the requested number of intervals `%s' is bad\n",
- progname, optarg);
- errcnt++;
- }
- else
- spec_no_of_intervals = true;
- break;
- case 'P':
- if (sscanf (optarg, "%d", &local_precision) <= 0)
- {
- fprintf (stderr, "%s: error: the requested precision `%s' is bad (it should be a positive integer)\n",
- progname, optarg);
- errcnt++;
- }
- else
- {
- if (local_precision <= 0)
- fprintf (stderr,
- "%s: the precision value `%s' is disregarded (it should be a positive integer)\n",
- progname, optarg);
- else
- precision = local_precision;
- }
- break;
-
- case 'a':
- auto_abscissa = AUTO_INCREMENT;
- if (optind >= argc)
- break;
- if (sscanf (argv[optind], "%lf", &local_delta_t) <= 0)
- break;
- delta_t = local_delta_t;
- optind++;
- if (optind >= argc)
- break;
- if (sscanf (argv [optind], "%lf", &local_t_start) <= 0)
- break;
- t_start = local_t_start;
- optind++;
- break;
-
- case 't':
- case 'x':
- if (sscanf (optarg, "%lf", &local_first_t) <= 0)
- break;
- first_t = local_first_t;
- spec_first_t = true;
- if (optind >= argc)
- break;
- if (sscanf (argv [optind], "%lf", &local_last_t) <= 0)
- break;
- last_t = local_last_t;
- spec_last_t = true;
- optind++;
- if (optind >= argc)
- break;
- if (sscanf (argv [optind], "%lf", &local_spacing_t) <= 0)
- break;
- spacing_t = local_spacing_t;
- spec_spacing_t = true;
- optind++;
- break;
-
- default:
- errcnt++;
- break;
- }
- if ((option == EOF))
- {
- errcnt--;
- break;
- }
- }
-
- if (errcnt > 0)
- {
- fprintf (stderr, "Try `%s --help' for more information\n", progname);
- return EXIT_FAILURE;
- }
- if (show_version)
- {
- display_version (progname, written, copyright);
- return EXIT_SUCCESS;
- }
- if (show_usage)
- {
- display_usage (progname, hidden_options, usage_appendage, 0);
- return EXIT_SUCCESS;
- }
-
- if (no_of_intervals < 1)
- {
- fprintf (stderr,
- "%s: error: the abscissa range cannot be subdivided into %d intervals\n",
- progname, no_of_intervals);
- return EXIT_FAILURE;
- }
- if (periodic)
- {
- if (spec_boundary_condition)
- fprintf (stderr,
- "%s: the setting of a boundary condition is not supported for a periodic spline\n",
- progname);
- boundary_condition = 0.0;
- }
- if (filter)
-
- {
- if (!spec_first_t || !spec_last_t)
- {
- fprintf (stderr,
- "%s: error: acting as a filter, so the abscissa range should be specified with the -t option\n",
- progname);
- return EXIT_FAILURE;
- }
- if (!spec_spacing_t)
- spacing_t = (last_t - first_t) / no_of_intervals;
- else
- {
- if (spec_no_of_intervals)
- fprintf (stderr, "%s: the requested number of intervals is disregarded\n",
- progname);
- if ((last_t - first_t) * spacing_t < 0.0)
- {
- fprintf (stderr, "%s: the requested spacing was of the wrong sign, so it has been corrected\n",
- progname);
- spacing_t = -spacing_t;
- }
-
- }
-
- if (spec_boundary_condition)
- fprintf (stderr,
- "%s: acting as a filter, so the setting of a boundary condition is not supported\n",
- progname);
- if (tension != 0.0)
- fprintf (stderr,
- "%s: acting as a filter, so nonzero tension is not supported\n",
- progname);
- if (periodic)
- fprintf (stderr,
- "%s: acting as a filter, so periodicity is not supported\n",
- progname);
- if (optind < argc)
- {
-
- for (; optind < argc; optind++)
- {
- FILE *data_file;
-
-
- if (strcmp (argv[optind], "-") == 0)
- data_file = stdin;
- else
- {
- data_file = fopen (argv[optind], "r");
- if (data_file == NULL)
- {
- fprintf (stderr, "%s: %s: %s\n", progname, argv[optind], strerror(errno));
- return EXIT_FAILURE;
- }
- }
-
- do
- {
- dataset_follows = do_bessel (data_file, ydimension,
- auto_abscissa, t_start, delta_t,
- first_t, last_t, spacing_t,
- precision, suppress_abscissa);
-
- if (dataset_follows || (optind + 1 != argc))
- output_dataset_separator();
-
- } while (dataset_follows);
-
- if (data_file != stdin)
- {
- if (fclose (data_file) < 0)
- {
- fprintf (stderr,
- "%s: error: the input file `%s' could not be closed\n",
- progname, argv[optind]);
- return EXIT_FAILURE;
- }
- }
- }
- }
- else
-
- do
- {
- dataset_follows = do_bessel (stdin, ydimension,
- auto_abscissa, t_start, delta_t,
- first_t, last_t, spacing_t,
- precision, suppress_abscissa);
-
-
- if (dataset_follows)
- output_dataset_separator();
- }
- while (dataset_follows);
- }
- else
-
- {
- double *t, **y, **z;
- int i, len, used;
- if (optind < argc)
- {
-
- for (; optind < argc; optind++)
- {
- FILE *data_file;
-
-
- if (strcmp (argv[optind], "-") == 0)
- data_file = stdin;
- else
- {
- data_file = fopen (argv[optind], "r");
- if (data_file == NULL)
- {
- fprintf (stderr, "%s: error: the file `%s' could not be opened\n",
- progname, argv[optind]);
- return EXIT_FAILURE;
- }
- }
-
-
- do
- {
- len = 16;
- used = -1;
-
- t = (double *)xmalloc (sizeof(double) * len);
- y = (double **)xmalloc (sizeof(double *) * ydimension);
- z = (double **)xmalloc (sizeof(double *) * ydimension);
- for (i = 0; i < ydimension; i++)
- {
- y[i] = (double *)xmalloc (sizeof(double) * len);
- z[i] = (double *)xmalloc (sizeof(double) * len);
- }
-
- dataset_follows = read_data (data_file, &len, &used,
- auto_abscissa, t_start, delta_t,
- &t, ydimension, y, z);
-
-
-
- do_spline (used, len,
- &t, ydimension, y, z, tension, periodic,
- spec_boundary_condition, boundary_condition,
- precision,
- first_t, last_t, spacing_t, no_of_intervals,
- spec_first_t, spec_last_t, spec_spacing_t,
- spec_no_of_intervals, suppress_abscissa);
-
- if (dataset_follows || (optind + 1 != argc))
- output_dataset_separator();
-
- free (z);
- free (y);
- free (t);
- }
- while (dataset_follows);
-
-
- if (data_file != stdin)
- {
- if (fclose (data_file) < 0)
- {
- fprintf (stderr,
- "%s: error: the input file `%s' could not be closed\n",
- progname, argv[optind]);
- return EXIT_FAILURE;
- }
- }
- }
- }
- else
-
- do
- {
- len = 16;
- used = -1;
-
- t = (double *)xmalloc (sizeof(double) * len);
- y = (double **)xmalloc (sizeof(double *) * ydimension);
- z = (double **)xmalloc (sizeof(double *) * ydimension);
- for (i = 0; i < ydimension; i++)
- {
- y[i] = (double *)xmalloc (sizeof(double) * len);
- z[i] = (double *)xmalloc (sizeof(double) * len);
- }
-
- dataset_follows = read_data (stdin, &len, &used,
- auto_abscissa, t_start, delta_t,
- &t, ydimension, y, z);
-
-
-
- do_spline (used, len,
- &t, ydimension, y, z, tension, periodic,
- spec_boundary_condition, boundary_condition, precision,
- first_t, last_t, spacing_t, no_of_intervals,
- spec_first_t, spec_last_t, spec_spacing_t,
- spec_no_of_intervals, suppress_abscissa);
-
-
- if (dataset_follows)
- output_dataset_separator();
-
- for (i = 0; i < ydimension; i++)
- {
- free (z[i]);
- free (y[i]);
- }
- free (z);
- free (y);
- free (t);
- }
- while (dataset_follows);
-
- }
- return EXIT_SUCCESS;
- }
- void
- set_format_type (char *s, data_type *typep)
- {
- switch (s[0])
- {
- case 'a':
- case 'A':
- *typep = T_ASCII;
- break;
- case 'f':
- case 'F':
- *typep = T_SINGLE;
- break;
- case 'd':
- case 'D':
- *typep = T_DOUBLE;
- break;
- case 'i':
- case 'I':
- *typep = T_INTEGER;
- break;
- default:
- {
- fprintf (stderr, "%s: error: the data format type `%s' is invalid\n",
- progname, s);
- exit (EXIT_FAILURE);
- }
- break;
- }
- }
- void
- fit (int n, double *t, double *y, double *z, double k, double tension,
- bool periodic)
- {
- double *h, *b, *u, *v, *alpha, *beta;
- double *uu = NULL, *vv = NULL, *s = NULL;
- int i;
- if (n == 1)
- {
- z[0] = z[1] = 0.0;
- return;
- }
- h = (double *)xmalloc (sizeof(double) * n);
- b = (double *)xmalloc (sizeof(double) * n);
- u = (double *)xmalloc (sizeof(double) * n);
- v = (double *)xmalloc (sizeof(double) * n);
- alpha = (double *)xmalloc (sizeof(double) * n);
- beta = (double *)xmalloc (sizeof(double) * n);
- if (periodic)
- {
- s = (double *)xmalloc (sizeof(double) * n);
- uu = (double *)xmalloc (sizeof(double) * n);
- vv = (double *)xmalloc (sizeof(double) * n);
- }
- for (i = 0; i <= n - 1 ; ++i)
- {
- h[i] = t[i + 1] - t[i];
- b[i] = 6.0 * (y[i + 1] - y[i]) / h[i];
- }
- if (tension < 0.0)
- {
- for (i = 0; i <= n - 1 ; ++i)
- if (sin (tension * h[i]) == 0.0)
- {
- fprintf (stderr, "%s: error: the specified negative tension value is singular\n", progname);
- exit (EXIT_FAILURE);
- }
- }
- if (tension == 0.0)
- {
- for (i = 0; i <= n - 1 ; ++i)
- {
- alpha[i] = h[i];
- beta[i] = 2.0 * h[i];
- }
- }
- else
- if (tension > 0.0)
-
- {
- for (i = 0; i <= n - 1 ; ++i)
- {
- double x = tension * h[i];
- double xabs = (x < 0.0 ? -x : x);
- if (xabs < TRIG_ARG_MIN)
-
- {
- alpha[i] = h[i] * sinh_func(x);
- beta[i] = 2.0 * h[i] * tanh_func(x);
- }
- else if (xabs > TRIG_ARG_MAX)
-
- {
- int sign = (x < 0.0 ? -1 : 1);
- alpha[i] = ((6.0 / (tension * tension))
- * ((1.0 / h[i]) - tension * 2 * sign * exp(-xabs)));
- beta[i] = ((6.0 / (tension * tension))
- * (tension - (1.0 / h[i])));
- }
- else
- {
- alpha[i] = ((6.0 / (tension * tension))
- * ((1.0 / h[i]) - tension / sinh(x)));
- beta[i] = ((6.0 / (tension * tension))
- * (tension / tanh(x) - (1.0 / h[i])));
- }
- }
- }
- else
-
- {
- for (i = 0; i <= n - 1 ; ++i)
- {
- double x = tension * h[i];
- double xabs = (x < 0.0 ? -x : x);
- if (xabs < TRIG_ARG_MIN)
-
- {
- alpha[i] = h[i] * sin_func(x);
- beta[i] = 2.0 * h[i] * tan_func(x);
- }
- else
- {
- alpha[i] = ((6.0 / (tension * tension))
- * ((1.0 / h[i]) - tension / sin(x)));
- beta[i] = ((6.0 / (tension * tension))
- * (tension / tan(x) - (1.0 / h[i])));
- }
- }
- }
-
- if (!periodic && n == 2)
- u[1] = beta[0] + beta[1] + 2 * k * alpha[0];
- else
- u[1] = beta[0] + beta[1] + k * alpha[0];
- v[1] = b[1] - b[0];
-
- if (u[1] == 0.0)
- {
- fprintf (stderr,
- "%s: error: as posed, the problem of computing a spline is singular\n",
- progname);
- exit (EXIT_FAILURE);
- }
- if (periodic)
- {
- s[1] = alpha[0];
- uu[1] = 0.0;
- vv[1] = 0.0;
- }
- for (i = 2; i <= n - 1 ; ++i)
- {
- u[i] = (beta[i] + beta[i - 1]
- - alpha[i - 1] * alpha[i - 1] / u[i - 1]
- + (i == n - 1 ? k * alpha[n - 1] : 0.0));
- if (u[i] == 0.0)
- {
- fprintf (stderr,
- "%s: error: as posed, the problem of computing a spline is singular\n",
- progname);
- exit (EXIT_FAILURE);
- }
- v[i] = b[i] - b[i - 1] - alpha[i - 1] * v[i - 1] / u[i - 1];
- if (periodic)
- {
- s[i] = - s[i-1] * alpha[i-1] / u[i-1];
- uu[i] = uu[i-1] - s[i-1] * s[i-1] / u[i-1];
- vv[i] = vv[i-1] - v[i-1] * s[i-1] / u[i-1];
- }
- }
-
- if (!periodic)
- {
-
- z[n] = 0.0;
- for (i = n - 1; i >= 1; --i)
- z[i] = (v[i] - alpha[i] * z[i + 1]) / u[i];
- z[0] = 0.0;
-
-
- z[0] = k * z[1];
- z[n] = k * z[n - 1];
- }
- else
- {
- z[n-1] = (v[n-1] + vv[n-1]) / (u[n-1] + uu[n-1] + 2 * s[n-1]);
- for (i = n - 2; i >= 1; --i)
- z[i] = ((v[i] - alpha[i] * z[i + 1]) - s[i] * z[n-1]) / u[i];
- z[0] = z[n-1];
- z[n] = z[1];
- }
- if (periodic)
- {
- free (vv);
- free (uu);
- free (s);
- }
- free (beta);
- free (alpha);
- free (v);
- free (u);
- free (b);
- free (h);
- }
- double
- interpolate (int n, double *t, double *y, double *z, double x,
- double tension, bool periodic)
- {
- double diff, updiff, reldiff, relupdiff, h;
- double value;
- int is_ascending = (t[n-1] < t[n]);
- int i = 0, k;
-
- if (periodic && (x - t[0]) * (x - t[n]) > 0.0)
- x -= ((int)(floor( (x - t[0]) / (t[n] - t[0]) )) * (t[n] - t[0]));
-
- for (k = n - i; k > 1;)
- {
- if (is_ascending ? x >= t[i + (k>>1)] : x <= t[i + (k>>1)])
- {
- i = i + (k>>1);
- k = k - (k>>1);
- }
- else
- k = k>>1;
- }
-
- h = t[i + 1] - t[i];
- diff = x - t[i];
- updiff = t[i+1] - x;
- reldiff = diff / h;
- relupdiff = updiff / h;
- if (tension == 0.0)
-
- value = y[i]
- + diff
- * ((y[i + 1] - y[i]) / h - h * (z[i + 1] + z[i] * 2.0) / 6.0
- + diff * (0.5 * z[i] + diff * (z[i + 1] - z[i]) / (6.0 * h)));
-
- else if (tension > 0.0)
-
- {
- if (fabs(tension * h) < TRIG_ARG_MIN)
-
- value = (y[i] * relupdiff + y[i+1] * reldiff
- + ((z[i] * h * h / 6.0)
- * quotient_sinh_func (relupdiff, tension * h))
- + ((z[i+1] * h * h / 6.0)
- * quotient_sinh_func (reldiff, tension * h)));
- else if (fabs(tension * h) > TRIG_ARG_MAX)
-
- {
- int sign = (h < 0.0 ? -1 : 1);
- value = (((z[i] * (exp (tension * updiff - sign * tension * h)
- + exp (-tension * updiff - sign * tension * h))
- + z[i + 1] * (exp (tension * diff - sign * tension * h)
- + exp (-tension * diff - sign * tension*h)))
- * (sign / (tension * tension)))
- + (y[i] - z[i] / (tension * tension)) * (updiff / h)
- + (y[i + 1] - z[i + 1] / (tension * tension)) * (diff / h));
- }
- else
- value = (((z[i] * sinh (tension * updiff)
- + z[i + 1] * sinh (tension * diff))
- / (tension * tension * sinh (tension * h)))
- + (y[i] - z[i] / (tension * tension)) * (updiff / h)
- + (y[i + 1] - z[i + 1] / (tension * tension)) * (diff / h));
- }
- else
-
- {
- if (fabs(tension * h) < TRIG_ARG_MIN)
-
- value = (y[i] * relupdiff + y[i+1] * reldiff
- + ((z[i] * h * h / 6.0)
- * quotient_sin_func (relupdiff, tension * h))
- + ((z[i+1] * h * h / 6.0)
- * quotient_sin_func (reldiff, tension * h)));
- else
- value = (((z[i] * sin (tension * updiff)
- + z[i + 1] * sin (tension * diff))
- / (tension * tension * sin (tension * h)))
- + (y[i] - z[i] / (tension * tension)) * (updiff / h)
- + (y[i + 1] - z[i + 1] / (tension * tension)) * (diff / h));
- }
-
- return value;
- }
- bool
- is_monotonic (int n, double *t)
- {
- bool is_ascending;
- if (t[n-1] < t[n])
- is_ascending = true;
- else if (t[n-1] > t[n])
- is_ascending = false;
- else
- return false;
- while (n>0)
- {
- n--;
- if (is_ascending == true ? t[n] >= t[n+1] : t[n] <= t[n+1])
- return false;
- };
- return true;
- }
- bool
- read_float (FILE *input, double *dptr)
- {
- int num_read;
- double dval;
- float fval;
- int ival;
- switch (input_type)
- {
- case T_ASCII:
- default:
- num_read = fscanf (input, "%lf", &dval);
- break;
- case T_SINGLE:
- num_read = fread ((void *) &fval, sizeof (fval), 1, input);
- dval = fval;
- break;
- case T_DOUBLE:
- num_read = fread ((void *) &dval, sizeof (dval), 1, input);
- break;
- case T_INTEGER:
- num_read = fread ((void *) &ival, sizeof (ival), 1, input);
- dval = ival;
- break;
- }
- if (num_read <= 0)
- return false;
- if (dval != dval)
- {
- fprintf (stderr, "%s: a NaN (not-a-number) was encountered in a binary input file (it is treated as EOF)\n",
- progname);
- return false;
- }
- else
- {
- *dptr = dval;
- return true;
- }
- }
- bool
- write_point (double t, double *y, int ydimension, int precision, bool suppress_abscissa)
- {
- int i, num_written = 0;
- float ft, fy;
- int it, iy;
- switch (output_type)
- {
- case T_ASCII:
- default:
- if (suppress_abscissa == false)
- num_written += printf ("%.*g ", precision, t);
- for (i = 0; i < ydimension - 1; i++)
- num_written += printf ("%.*g ", precision, y[i]);
- num_written += printf ("%.*g\n", precision, y[ydimension - 1]);
- break;
- case T_SINGLE:
- if (suppress_abscissa == false)
- {
- ft = FROUND(t);
- if (ft == FLT_MAX || ft == -(FLT_MAX))
- {
- maybe_emit_oob_warning();
- if (ft == FLT_MAX)
- ft *= 0.99999;
- }
- num_written += fwrite ((void *) &ft, sizeof (ft), 1, stdout);
- }
- for (i = 0; i < ydimension; i++)
- {
- fy = y[i];
- if (fy == FLT_MAX || fy == -(FLT_MAX))
- {
- maybe_emit_oob_warning();
- if (fy == FLT_MAX)
- fy *= 0.99999;
- }
- num_written += fwrite ((void *) &fy, sizeof (fy), 1, stdout);
- }
- break;
- case T_DOUBLE:
- if (suppress_abscissa == false)
- num_written += fwrite ((void *) &t, sizeof (t), 1, stdout);
- for (i = 0; i < ydimension; i++)
- num_written += fwrite ((void *) &(y[i]), sizeof (double), 1, stdout);
- break;
- case T_INTEGER:
- if (suppress_abscissa == false)
- {
- it = IROUND(t);
- if (it == INT_MAX || it == -(INT_MAX))
- {
- maybe_emit_oob_warning();
- if (it == INT_MAX)
- it--;
- }
- num_written += fwrite ((void *) &it, sizeof (it), 1, stdout);
- }
- for (i = 0; i < ydimension; i++)
- {
- iy = IROUND(y[i]);
- if (iy == INT_MAX || iy == -(INT_MAX))
- {
- maybe_emit_oob_warning();
- if (iy == INT_MAX)
- iy--;
- }
- num_written += fwrite ((void *) &iy, sizeof (iy), 1, stdout);
- }
- break;
- }
-
- return (num_written > 0 ? true : false);
- }
- int
- read_point (FILE *input, double *t, double *y, int ydimension,
- bool *first_point,
- int auto_abscissa, double *auto_t, double auto_delta,
- double *stored)
- {
- bool success;
- int i, items_read, lookahead;
- head:
- if (input_type == T_ASCII)
- {
- bool two_newlines;
-
- two_newlines = skip_whitespace (input);
- if (two_newlines)
-
- return 2;
- }
- if (feof (input))
- return 1;
- if (input_type == T_ASCII)
- {
- lookahead = getc (input);
- ungetc (lookahead, input);
- if (lookahead == (int)'#')
- {
- char c;
-
- do
- {
- items_read = fread (&c, sizeof (c), 1, input);
- if (items_read <= 0)
- return 1;
- }
- while (c != '\n');
- ungetc ((int)'\n', input);
- goto head;
- }
- }
- if (auto_abscissa != AUTO_NONE)
- {
-
- success = read_float (input, &(y[0]));
- if (!success)
- return 1;
- if ((input_type == T_DOUBLE && y[0] == DBL_MAX)
- || (input_type == T_SINGLE && y[0] == (double)FLT_MAX)
- || (input_type == T_INTEGER && y[0] == (double)INT_MAX))
-
- return 2;
-
- for (i = 1; i < ydimension; i++)
- {
- success = read_float (input, &(y[i]));
- if (!success)
- {
- fprintf (stderr, "%s: an input file terminated prematurely\n",
- progname);
- return 1;
- }
- }
-
- if (auto_abscissa == AUTO_INCREMENT)
- {
- *t = *auto_t;
- *auto_t += auto_delta;
- }
- else
- {
- if (*first_point == true)
- {
- *t = *auto_t;
- *first_point = false;
- }
- else
- {
- double distsq = 0.0;
- for (i = 0; i < ydimension; i++)
- distsq += (y[i] - stored[i])*(y[i] - stored[i]);
- *auto_t += sqrt (distsq);
- *t = *auto_t;
- }
- for (i = 0; i < ydimension; i++)
- stored[i] = y[i];
- }
-
- return 0;
- }
- else
- {
-
- success = read_float (input, t);
- if (!success)
- return 1;
- if ((input_type == T_DOUBLE && *t == DBL_MAX)
- || (input_type == T_SINGLE && *t == (double)FLT_MAX)
- || (input_type == T_INTEGER && *t == (double)INT_MAX))
-
- return 2;
-
- for (i = 0; i < ydimension; i++)
- {
- success = read_float (input, &(y[i]));
- if (!success)
- {
- fprintf (stderr, "%s: an input file terminated prematurely\n",
- progname);
- return 1;
- }
- }
-
- return 0;
- }
- }
- bool
- read_data (FILE *input, int *len, int *used, int auto_abscissa,
- double auto_t, double auto_delta,
- double **t, int ydimension, double **y, double **z)
- {
- bool first = true;
- int i, success;
- double tt, *yy, *stored;
- yy = (double *)xmalloc (sizeof(double) * ydimension);
- stored = (double *)xmalloc (sizeof(double) * ydimension);
- for ( ; ; )
- {
- if ((++ *used) >= *len)
- {
- *len *= 2;
- *t = (double *)xrealloc (*t, sizeof(double) * *len);
- for (i = 0; i < ydimension; i++)
- {
- y[i] = (double *)xrealloc (y[i], sizeof(double) * *len);
- z[i] = (double *)xrealloc (z[i], sizeof(double) * *len);
- }
- }
- success = read_point (input, &tt, yy, ydimension, &first,
- auto_abscissa, &auto_t, auto_delta, stored);
- switch (success)
- {
- case 0:
- (*t)[*used] = tt;
- for (i = 0; i < ydimension; i++)
- y[i][*used] = yy[i];
- break;
- case 1:
- (*used)--;
- free (stored);
- free (yy);
- return false;
- case 2:
- (*used)--;
- free (stored);
- free (yy);
- return true;
- }
- }
- }
- void
- do_spline (int used, int len, double **t, int ydimension, double **y, double **z,
- double tension, bool periodic, bool spec_boundary_condition,
- double k, int precision, double first_t, double last_t,
- double spacing_t, int no_of_intervals, bool spec_first_t,
- bool spec_last_t, bool spec_spacing_t,
- bool spec_no_of_intervals, bool suppress_abscissa)
- {
- int range_count = 0;
- int lastval = 0;
- int i;
- if (used + 1 == 0)
-
- return;
- if (used+1 == 1)
- {
- fprintf (stderr,
- "%s: a spline cannot be constructed from a single data point\n",
- progname);
-
- return;
- }
- if (!periodic && used+1 <= 2)
- {
- if (spec_boundary_condition)
- fprintf (stderr,
- "%s: the specified boundary condition is ignored, as there are only 2 data points\n",
- progname);
- k = 0.0;
- }
- if (!is_monotonic (used, *t))
- non_monotonic_error();
- if (periodic)
- {
- bool print_warning = false;
-
- for (i = 0; i < ydimension; i++)
- {
- if (y[i][used] != y[i][0])
- print_warning = true;
- y[i][used] = y[i][0];
- }
- if (print_warning == true)
- fprintf (stderr, "%s: the final y value is set equal to the initial value, to ensure periodicity\n",
- progname);
-
- if (used + 1 >= len)
- {
- len++;
- *t = (double *)xrealloc (*t, sizeof(double) * len);
- for (i = 0; i < ydimension; i++)
- {
- y[i] = (double *)xrealloc (y[i], sizeof(double) * len);
- z[i] = (double *)xrealloc (z[i], sizeof(double) * len);
- }
- }
- (*t)[used + 1] = (*t)[used] + ((*t)[1] - (*t)[0]);
- for (i = 0; i < ydimension; i++)
- y[i][used + 1] = y[i][1];
- }
-
- for (i = 0; i < ydimension; i++)
- fit (used + (periodic ? 1 : 0),
- *t, y[i], z[i], k, tension, periodic);
- if (!spec_first_t)
- first_t = (*t)[0];
- if (!spec_last_t)
- last_t = (*t)[used];
- if (!spec_spacing_t)
- {
- if (no_of_intervals > 0)
- spacing_t = (last_t - first_t) / no_of_intervals;
- else
- spacing_t = 0;
- }
- else
- {
- if ((last_t - first_t) * spacing_t < 0.0)
- {
- fprintf (stderr, "%s: the requested spacing is of the wrong sign, so it has been corrected\n",
- progname);
- spacing_t = -spacing_t;
- }
- if (spec_no_of_intervals)
- fprintf (stderr, "%s: the requested number of intervals is disregarded\n",
- progname);
- no_of_intervals = (int)(fabs((last_t - first_t) / spacing_t) + FUZZ);
- }
- if (last_t == (*t)[0])
- lastval = 1;
- else if (last_t == (*t)[used])
- lastval = 2;
- for (i = 0; i <= no_of_intervals; ++i)
- {
- double x;
- x = first_t + spacing_t * i;
- if (i == no_of_intervals)
- {
-
- if (lastval == 1)
- x = (*t)[0];
- else if (lastval == 2)
- x = (*t)[used];
- }
- if (periodic || (x - (*t)[0]) * (x - (*t)[used]) <= 0)
- {
- int j;
- double *yy;
- yy = (double *)xmalloc (sizeof(double) * ydimension);
- for (j = 0; j < ydimension; j++)
- yy[j] = interpolate (used, *t, y[j], z[j], x,
- tension, periodic);
- write_point (x, yy, ydimension, precision, suppress_abscissa);
- free (yy);
- }
- else
- range_count++;
- }
- switch (range_count)
- {
- case 0:
- break;
- case 1:
- fprintf (stderr,
- "%s: one requested point could not be computed (as it was out of the data range)\n",
- progname);
- break;
- default:
- fprintf (stderr,
- "%s: %d requested points could not be computed (as they were out of the data range)\n",
- progname, range_count);
- break;
- }
- }
- bool
- do_bessel (FILE *input, int ydimension, int auto_abscissa, double auto_t,
- double auto_delta, double first_t, double last_t,
- double spacing_t, int precision, bool suppress_abscissa)
- {
- bool first = true;
- double t, *y, *s0, *s1, *s2, *stored;
- double tt[4], **yy;
- int direction = (last_t > first_t ? 1 : -1);
- int state = STATE_ZERO;
- int i, success;
- y = (double *)xmalloc (sizeof(double) * ydimension);
- s0 = (double *)xmalloc (sizeof(double) * ydimension);
- s1 = (double *)xmalloc (sizeof(double) * ydimension);
- s2 = (double *)xmalloc (sizeof(double) * ydimension);
- yy = (double **)xmalloc (4 * sizeof(double *));
- stored = (double *)xmalloc (sizeof(double) * ydimension);
- for (i = 0; i < 4; i++)
- yy[i] = (double *)xmalloc (ydimension * sizeof(double));
- for ( ; ; )
- {
- success = read_point (input, &t, y, ydimension, &first,
- auto_abscissa, &auto_t, auto_delta, stored);
-
- if (success == 0)
- {
-
- switch (state)
- {
- case STATE_ZERO:
- tt[0] = t;
- for (i = 0; i < ydimension; i++)
- yy[0][i] = y[i];
- state = STATE_ONE;
- break;
- case STATE_ONE:
- tt[1] = t;
- if (direction * (tt[1] - tt[0]) <= 0)
- non_monotonic_error();
- for (i = 0; i < ydimension; i++)
- yy[1][i] = y[i];
- state = STATE_TWO;
- break;
- case STATE_TWO:
- tt[2] = t;
- if (direction * (tt[2] - tt[1]) <= 0)
- non_monotonic_error();
- for (i = 0; i < ydimension; i++)
- {
- yy[2][i] = y[i];
-
-
- s0[i] = (((tt[1]-tt[0]) * ((yy[0][i]-yy[2][i]) / (tt[0]-tt[2]))
- + (tt[0]-tt[2]) * ((yy[1][i]-yy[0][i]) / (tt[1]-tt[0])))
- / (tt[1]-tt[2]));
- s1[i] = (((tt[2]-tt[1]) * ((yy[1][i]-yy[0][i]) / (tt[1]-tt[0]))
- + (tt[1]-tt[0]) * ((yy[2][i]-yy[1][i]) / (tt[2]-tt[1])))
- / (tt[2]-tt[0]));
- }
-
- do_bessel_range (tt[0], tt[1], yy[0], yy[1], s0, s1,
- first_t, last_t, spacing_t,
- ydimension, precision, false,
- suppress_abscissa);
-
- state = STATE_THREE;
- break;
- case STATE_THREE:
- tt[3] = t;
- if (direction * (tt[3] - tt[2]) <= 0)
- non_monotonic_error();
- for (i = 0; i < ydimension; i++)
- {
- yy[3][i] = y[i];
-
-
- s2[i] = (((tt[3]-tt[2]) * ((yy[2][i]-yy[1][i]) / (tt[2]-tt[1]))
- + (tt[2]-tt[1]) * ((yy[3][i]-yy[2][i]) / (tt[3]-tt[2])))
- / (tt[3]-tt[1]));
- }
-
-
- do_bessel_range (tt[1], tt[2], yy[1], yy[2], s1, s2,
- first_t, last_t, spacing_t,
- ydimension, precision, false,
- suppress_abscissa);
-
-
- tt[0] = tt[1];
- tt[1] = tt[2];
- tt[2] = tt[3];
- for (i = 0; i < ydimension; i++)
- {
- yy[0][i] = yy[1][i];
- yy[1][i] = yy[2][i];
- yy[2][i] = yy[3][i];
-
- s1[i] = s2[i];
- }
- break;
- }
- }
- else
- {
- switch (state)
- {
- case STATE_ZERO:
-
- break;
- case STATE_ONE:
- fprintf (stderr, "%s: a spline cannot be constructed from a single data point\n",
- progname);
-
- break;
- case STATE_TWO:
-
- for (i = 0; i < ydimension; i++)
- s0[i] = s1[i] = (yy[1][i] - yy[0][i])/(tt[1]-tt[0]);
- do_bessel_range (tt[0], tt[1], yy[0], yy[1], s0, s1,
- first_t, last_t, spacing_t,
- ydimension, precision, true,
- suppress_abscissa);
- break;
- case STATE_THREE:
-
-
- for (i = 0; i < ydimension; i++)
- s2[i] = (((tt[0]-tt[2]) * ((yy[2][i]-yy[1][i]) / (tt[2]-tt[1]))
- + (tt[2]-tt[1]) * ((yy[0][i]-yy[2][i]) / (tt[0]-tt[2])))
- / (tt[0]-tt[1]));
-
- do_bessel_range (tt[1], tt[2], yy[1], yy[2], s1, s2,
- first_t, last_t, spacing_t,
- ydimension, precision, true,
- suppress_abscissa);
- break;
- }
-
- for (i = 0; i < 4; i++)
- free (yy[i]);
- free (stored);
- free (yy);
- free (s2);
- free (s1);
- free (s0);
- free (y);
-
- return (success == 2 ? true : false);
- }
- }
- }
- void
- non_monotonic_error (void)
- {
- fprintf (stderr, "%s: error: the abscissa values are not monotonic\n",
- progname);
- exit (EXIT_FAILURE);
- }
- void
- do_bessel_range (double abscissa0, double abscissa1, double *value0,
- double *value1, double *slope0, double *slope1,
- double first_t, double last_t, double spacing_t,
- int ydimension, int precision, bool endit,
- bool suppress_abscissa)
- {
- int direction = ((last_t > first_t) ? 1 : -1);
- int i, j;
- int imin1 = (int)((abscissa0 - first_t) / spacing_t - 1);
- int imax1 = (int)((abscissa1 - first_t) / spacing_t + 1);
- int imin2 = 0;
- int imax2 = (int)((last_t - first_t) / spacing_t + 1);
- int imin, imax;
-
-
- imin = IMAX (imin1, imin2);
- imax = IMIN (imax1, imax2);
- for (i = imin; i <= imax; i++)
- {
- double t;
- t = first_t + i * spacing_t;
- if ((direction * t >= direction * abscissa0)
- && (direction * t >= direction * first_t)
-
- && ((direction * t < (direction
- * (abscissa1
- + (endit ?
- FUZZ * (abscissa1 - abscissa0) : 0.)))))
- && (direction * t <= (direction
- * (last_t
- + (endit ? FUZZ * (last_t - first_t) : 0.)))))
- {
- double diff = t - abscissa0;
- double updiff = abscissa1 - t;
- double h = abscissa1 - abscissa0;
- double *y;
- bool success;
- y = (double *)xmalloc (sizeof(double) * ydimension);
- for (j = 0; j < ydimension; j++)
- {
-
- y[j] = (value1[j] * (-2.0 * diff * diff * diff / (h * h * h)
- + 3.0 * diff * diff / (h * h))
- + value0[j] * (-2.0 * updiff * updiff * updiff / (h * h * h)
- + 3.0 * updiff * updiff / (h * h)))
- + ((slope1[j] * (diff * diff * diff / (h * h)
- - diff * diff / h)
- - (slope0[j] * (updiff * updiff * updiff / (h * h)
- - updiff * updiff / h))));
- }
-
- success = write_point (t, y,
- ydimension, precision, suppress_abscissa);
- if (!success)
- {
- fprintf (stderr,
- "%s: error: standard output cannot be written to\n",
- progname);
- exit (EXIT_FAILURE);
- }
- free (y);
- }
- }
- }
- void
- output_dataset_separator (void)
- {
- double ddummy;
- float fdummy;
- int idummy;
- switch (output_type)
- {
- case T_ASCII:
- default:
- printf ("\n");
- break;
- case T_DOUBLE:
- ddummy = DBL_MAX;
- fwrite ((void *) &ddummy, sizeof(ddummy), 1, stdout);
- break;
- case T_SINGLE:
- fdummy = FLT_MAX;
- fwrite ((void *) &fdummy, sizeof(fdummy), 1, stdout);
- break;
- case T_INTEGER:
- idummy = INT_MAX;
- fwrite ((void *) &idummy, sizeof(idummy), 1, stdout);
- break;
- }
- }
- bool
- skip_whitespace (FILE *stream)
- {
- int lookahead;
- int nlcount = 0;
-
- do
- {
- lookahead = getc (stream);
- if (lookahead == (int)'\n')
- nlcount++;
- }
- while (lookahead != EOF
- && isspace((unsigned char)lookahead)
- && nlcount < 2);
- if (lookahead == EOF)
- return false;
-
- ungetc (lookahead, stream);
- return (nlcount == 2 ? true : false);
- }
- void
- maybe_emit_oob_warning (void)
- {
- static bool warning_written = false;
- if (!warning_written)
- {
- fprintf (stderr, "%s: one or more out-of-bounds output values are approximated\n", progname);
- warning_written = true;
- }
- }
- double
- sinh_func (double x)
- {
-
- return 1.0 - (7.0/60.0)*x*x + (31.0/2520.0)*x*x*x*x;
- }
- double
- tanh_func (double x)
- {
-
- return 1.0 - (1.0/15.0)*x*x + (2.0/315.0)*x*x*x*x;
- }
- double
- sin_func (double x)
- {
-
- return -1.0 - (7.0/60.0)*x*x - (31.0/2520.0)*x*x*x*x;
- }
- double
- tan_func (double x)
- {
-
- return -1.0 - (1.0/15.0)*x*x - (2.0/315.0)*x*x*x*x;
- }
- double
- quotient_sinh_func (double x, double y)
- {
- return ((x*x*x-x) + (x*x*x*x*x/20.0 - x*x*x/6.0 + 7.0*x/60.0)*(y*y)
- + (x*x*x*x*x*x*x/840.0 - x*x*x*x*x/120.0 + 7.0*x*x*x/360.0
- -31.0*x/2520.0)*(y*y*y*y));
- }
- double
- quotient_sin_func (double x, double y)
- {
- return (- (x*x*x-x) + (x*x*x*x*x/20.0 - x*x*x/6.0 + 7.0*x/60.0)*(y*y)
- - (x*x*x*x*x*x*x/840.0 - x*x*x*x*x/120.0 + 7.0*x*x*x/360.0
- -31.0*x/2520.0)*(y*y*y*y));
- }
|