317 {
318 double *x = NULL, *y = NULL, *sy = NULL, *sx = NULL, *diff = NULL, xOffset,
319 xScaleFactor;
320 double *xOrig = NULL, *yOrig = NULL, *sxOrig, *syOrig, *sy0 = NULL;
321 long terms, normTerm, ySigmasValid;
322 int64_t i, j, points, pointsOrig;
323 long symmetry, chebyshev, autoOffset, copyParameters = 0;
324 double sigmas;
325 long sigmasMode, sparseInterval;
326 unsigned long flags;
327 double *coef, *coefSigma;
328 double chi, xLow, xHigh, rmsResidual;
329 char *xName, *yName, *xSigmaName, *ySigmaName;
330 char *input, *output, **coefUnits;
332 long isFit, iArg, modifySigmas;
333 long generateSigmas, verbose, ignoreSigmas;
334
335 long invalid = 0;
336 int32_t *order;
337 SCANNED_ARG *s_arg;
338 double xMin, xMax, revpowThreshold, revpowCompleteThres, goodEnoughChi;
339 long rangeFitOnly = 0;
340 double rms_average(double *d_x, int64_t d_n);
341 char *fitLabelFormat = "%g";
342 static char rpnSeqBuffer[SDDS_MAXLINE];
343 unsigned long pipeFlags, reviseOrders, majorOrderFlag;
345 short columnMajorOrder = -1;
346 long repeatFits = 0;
347
348 sxOrig = syOrig = NULL;
349 rmsResidual = 0;
350
352 argc =
scanargs(&s_arg, argc, argv);
353 if (argc < 2 || argc > (3 + N_OPTIONS)) {
354 fprintf(stderr, "usage: %s%s%s\n", USAGE, additional_help1,
355 additional_help2);
356 exit(EXIT_FAILURE);
357 }
358
359 input = output = NULL;
360 xName = yName = xSigmaName = ySigmaName = NULL;
361 modifySigmas = reviseOrders = chebyshev = 0;
362 order = NULL;
363 symmetry = NO_SYMMETRY;
364 xMin = xMax = 0;
365 autoOffset = 0;
366 generateSigmas = 0;
367 sigmasMode = -1;
368 sigmas = 1;
369 sparseInterval = 1;
370 terms = 2;
371 verbose = ignoreSigmas = 0;
372 normTerm = -1;
373 xOffset = 0;
374 xScaleFactor = 1;
375 coefUnits = NULL;
378 pipeFlags = 0;
379 evalParameters.file = evalParameters.valuesFile = evalParameters.valuesColumn = NULL;
380 evalParameters.initialized = evalParameters.inputInitialized = 0;
381
382 for (iArg = 1; iArg < argc; iArg++) {
383 if (s_arg[iArg].arg_type == OPTION) {
384 switch (
match_string(s_arg[iArg].list[0], option, N_OPTIONS, 0)) {
385 case CLO_REPEATFITS:
386 if (s_arg[iArg].n_items != 2 || sscanf(s_arg[iArg].list[1], "%ld", &repeatFits) != 1 || repeatFits < 1)
388 if (repeatFits<10)
389 SDDS_Bomb(
"The number of repeats should be at least 10");
390 break;
391 case CLO_MAJOR_ORDER:
392 majorOrderFlag = 0;
393 s_arg[iArg].n_items--;
394 if (s_arg[iArg].n_items > 0 &&
396 &s_arg[iArg].n_items, 0, "row", -1, NULL, 0,
397 SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0,
398 SDDS_COLUMN_MAJOR_ORDER, NULL)))
399 SDDS_Bomb(
"invalid -majorOrder syntax/values");
400 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
401 columnMajorOrder = 1;
402 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
403 columnMajorOrder = 0;
404 break;
405 case CLO_MODIFYSIGMAS:
406 modifySigmas = 1;
407 break;
408 case CLO_AUTOOFFSET:
409 autoOffset = 1;
410 break;
411 case CLO_ORDERS:
412 if (s_arg[iArg].n_items < 2)
414 order =
tmalloc(
sizeof(*order) * (terms = s_arg[iArg].n_items - 1));
415 for (i = 1; i < s_arg[iArg].n_items; i++) {
416 if (sscanf(s_arg[iArg].list[i], "%" SCNd32, order + i - 1) != 1)
417 SDDS_Bomb(
"unable to scan order from -orders list");
418 }
419 break;
420 case CLO_RANGE:
421 rangeFitOnly = 0;
422 if ((s_arg[iArg].n_items != 3 && s_arg[iArg].n_items != 4) ||
423 1 != sscanf(s_arg[iArg].list[1], "%lf", &xMin) ||
424 1 != sscanf(s_arg[iArg].list[2], "%lf", &xMax) || xMin >= xMax)
426 if (s_arg[iArg].n_items == 4) {
427 if (strncmp(
str_tolower(s_arg[iArg].list[3]),
"fitonly",
428 strlen(s_arg[iArg].list[3])) == 0) {
429 rangeFitOnly = 1;
430 } else
432 }
433 break;
434 case CLO_GENERATESIGMAS:
435 generateSigmas = FLGS_GENERATESIGMAS;
436 if (s_arg[iArg].n_items > 1) {
437 if (s_arg[iArg].n_items != 2)
438 SDDS_Bomb(
"incorrect -generateSigmas syntax");
439 if (strncmp(s_arg[iArg].list[1], "keepsmallest",
440 strlen(s_arg[iArg].list[1])) == 0)
441 generateSigmas |= FLGS_KEEPSMALLEST;
442 if (strncmp(s_arg[iArg].list[1], "keeplargest",
443 strlen(s_arg[iArg].list[1])) == 0)
444 generateSigmas |= FLGS_KEEPLARGEST;
445 if ((generateSigmas & FLGS_KEEPSMALLEST) &&
446 (generateSigmas & FLGS_KEEPLARGEST))
447 SDDS_Bomb(
"ambiguous -generateSigmas syntax");
448 }
449 break;
450 case CLO_TERMS:
451 if (s_arg[iArg].n_items != 2 ||
452 sscanf(s_arg[iArg].list[1], "%ld", &terms) != 1)
454 break;
455 case CLO_XOFFSET:
456 if (s_arg[iArg].n_items != 2 ||
457 sscanf(s_arg[iArg].list[1], "%lf", &xOffset) != 1)
459 break;
460 case CLO_SYMMETRY:
461 if (s_arg[iArg].n_items == 2) {
462 if ((symmetry =
match_string(s_arg[iArg].list[1], symmetry_options,
463 N_SYMMETRY_OPTIONS, 0)) < 0)
464 SDDS_Bomb(
"unknown option used with -symmetry");
465 } else
467 break;
468 case CLO_SIGMAS:
469 if (s_arg[iArg].n_items != 3)
471 if (sscanf(s_arg[iArg].list[1], "%lf", &sigmas) != 1)
472 SDDS_Bomb(
"couldn't scan value for -sigmas");
473 if ((sigmasMode =
match_string(s_arg[iArg].list[2], sigmas_options,
474 N_SIGMAS_OPTIONS, 0)) < 0)
476 break;
477 case CLO_SPARSE:
478 if (s_arg[iArg].n_items != 2)
480 if (sscanf(s_arg[iArg].list[1], "%ld", &sparseInterval) != 1)
481 SDDS_Bomb(
"couldn't scan value for -sparse");
482 if (sparseInterval < 1)
484 break;
485 case CLO_VERBOSE:
486 verbose = 1;
487 break;
488 case CLO_NORMALIZE:
489 normTerm = 0;
490 if (s_arg[iArg].n_items > 2 ||
491 (s_arg[iArg].n_items == 2 &&
492 sscanf(s_arg[iArg].list[1], "%ld", &normTerm) != 1) ||
493 normTerm < 0)
495 break;
496 case CLO_REVISEORDERS:
497 revpowThreshold = 0.1;
498 revpowCompleteThres = 10;
499 goodEnoughChi = 1;
500 s_arg[iArg].n_items -= 1;
502 &s_arg[iArg].n_items, 0,
504 "complete",
SDDS_DOUBLE, &revpowCompleteThres, 1, REVPOW_COMPLETE,
506 "verbose", -1, NULL, 1, REVPOW_VERBOSE, NULL) ||
507 revpowThreshold < 0 || revpowCompleteThres < 0 || goodEnoughChi < 0)
508 SDDS_Bomb(
"invalid -reviseOrders syntax");
509 reviseOrders |= REVPOW_ACTIVE;
510 break;
511 case CLO_CHEBYSHEV:
512 if (s_arg[iArg].n_items > 2 ||
513 (s_arg[iArg].n_items == 2 &&
514 strncmp(s_arg[iArg].list[1], "convert",
515 strlen(s_arg[iArg].list[1])) != 0))
517 chebyshev = s_arg[iArg].n_items;
520 break;
521 case CLO_XFACTOR:
522 if (s_arg[iArg].n_items != 2 ||
523 sscanf(s_arg[iArg].list[1], "%lf", &xScaleFactor) != 1 ||
524 xScaleFactor == 0)
526 break;
527 case CLO_COLUMNS:
528 if (s_arg[iArg].n_items < 3 || s_arg[iArg].n_items > 5)
530 xName = s_arg[iArg].list[1];
531 yName = s_arg[iArg].list[2];
532 s_arg[iArg].n_items -= 3;
533 if (!
scanItemList(&flags, s_arg[iArg].list + 3, &s_arg[iArg].n_items, 0,
534 "xsigma",
SDDS_STRING, &xSigmaName, 1, 0,
"ysigma",
537 break;
538 case CLO_FITLABELFORMAT:
539 if (s_arg[iArg].n_items != 2)
540 SDDS_Bomb(
"invalid -fitLabelFormat syntax");
541 fitLabelFormat = s_arg[iArg].list[1];
542 break;
543 case CLO_PIPE:
545 &pipeFlags))
547 break;
548 case CLO_EVALUATE:
549 if (s_arg[iArg].n_items < 2)
551 evalParameters.file = s_arg[iArg].list[1];
552 s_arg[iArg].n_items -= 2;
553 s_arg[iArg].list += 2;
554 if (!
scanItemList(&evalParameters.flags, s_arg[iArg].list,
555 &s_arg[iArg].n_items, 0,
556 "begin",
SDDS_DOUBLE, &evalParameters.begin, 1, EVAL_BEGIN_GIVEN,
557 "end",
SDDS_DOUBLE, &evalParameters.end, 1, EVAL_END_GIVEN,
558 "number",
SDDS_LONG64, &evalParameters.number, 1, EVAL_NUMBER_GIVEN,
559 "valuesfile",
SDDS_STRING, &evalParameters.valuesFile, 1, EVAL_VALUESFILE_GIVEN,
560 "valuescolumn",
SDDS_STRING, &evalParameters.valuesColumn, 1, EVAL_VALUESCOLUMN_GIVEN,
561 "reusepage", 0, NULL, 0, EVAL_REUSE_PAGE_GIVEN,
562 NULL))
564 if (evalParameters.flags & EVAL_VALUESFILE_GIVEN || evalParameters.flags & EVAL_VALUESCOLUMN_GIVEN) {
565 if (evalParameters.flags & (EVAL_BEGIN_GIVEN | EVAL_END_GIVEN | EVAL_NUMBER_GIVEN))
566 SDDS_Bomb(
"invalid -evaluate syntax: given begin/end/number or valuesFile/valuesColumn, not a mixture.");
567 if (!(evalParameters.flags & EVAL_VALUESFILE_GIVEN && evalParameters.flags & EVAL_VALUESCOLUMN_GIVEN))
568 SDDS_Bomb(
"invalid -evaluate syntax: give both valuesFile and valuesColumn, not just one");
569 }
570 evalParameters.initialized = 0;
571 break;
572 case CLO_COPY_PARAMETERS:
573 copyParameters = 1;
574 break;
575 default:
576 bomb(
"unknown switch", USAGE);
577 break;
578 }
579 } else {
580 if (input == NULL)
581 input = s_arg[iArg].list[0];
582 else if (output == NULL)
583 output = s_arg[iArg].list[0];
584 else
586 }
587 }
588
590
591 if (symmetry && order)
592 SDDS_Bomb(
"can't specify both -symmetry and -orders");
593 if (chebyshev && order)
594 SDDS_Bomb(
"can't specify both -chebyshev and -orders");
595 if (chebyshev && symmetry)
596 SDDS_Bomb(
"can't specify both -chebyshev and -symmetry");
597 if (!xName || !yName)
598 SDDS_Bomb(
"you must specify a column name for x and y");
599
600 if (modifySigmas && !xSigmaName)
601 SDDS_Bomb(
"you must specify x sigmas with -modifySigmas");
602 if (generateSigmas) {
603 if (modifySigmas)
604 SDDS_Bomb(
"you can't specify both -generateSigmas and -modifySigmas");
605 }
606 if (ySigmaName) {
607 if (sigmasMode != -1)
608 SDDS_Bomb(
"you can't specify both -sigmas and a y sigma name");
609 }
610 ySigmasValid = 0;
611 if (sigmasMode != -1 || generateSigmas || ySigmaName || modifySigmas)
612 ySigmasValid = 1;
613
614 if (normTerm >= 0 && normTerm >= terms)
615 SDDS_Bomb(
"can't normalize to that term--not that many terms");
616 if (reviseOrders && !(sigmasMode != -1 || generateSigmas || ySigmaName))
617 SDDS_Bomb(
"can't use -reviseOrders unless a y sigma or -generateSigmas is given");
618
619 if (symmetry == EVEN_SYMMETRY) {
620 order =
tmalloc(
sizeof(*order) * terms);
621 for (i = 0; i < terms; i++)
622 order[i] = 2 * i;
623 } else if (symmetry == ODD_SYMMETRY) {
624 order =
tmalloc(
sizeof(*order) * terms);
625 for (i = 0; i < terms; i++)
626 order[i] = 2 * i + 1;
627 } else if (!order) {
628 order =
tmalloc(
sizeof(*order) * terms);
629 for (i = 0; i < terms; i++)
630 order[i] = i;
631 }
632 coef =
tmalloc(
sizeof(*coef) * terms);
633 coefSigma =
tmalloc(
sizeof(*coefSigma) * terms);
634 iTerm =
tmalloc(
sizeof(*iTerm) * terms);
635 iTermSig =
tmalloc(
sizeof(*iTermSig) * terms);
636
639 checkInputFile(&SDDSin, xName, yName, xSigmaName, ySigmaName);
640 coefUnits = initializeOutputFile(&SDDSout, output, &SDDSin, input, xName,
641 yName, xSigmaName, ySigmaName, ySigmasValid,
642 order, terms, chebyshev, copyParameters, repeatFits);
643 if (columnMajorOrder != -1)
644 SDDSout.layout.data_mode.column_major = columnMajorOrder;
645 else
646 SDDSout.layout.data_mode.column_major =
647 SDDSin.layout.data_mode.column_major;
649
650 invalid = 0;
652 pointsOrig = 0;
653 invalid = 1;
654 isFit = 0;
655 } else {
657 fprintf(stderr, "error: unable to read column %s\n", xName);
659 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
660 }
662 fprintf(stderr, "error: unable to read column %s\n", yName);
664 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
665 }
666 sx = NULL;
668 fprintf(stderr, "error: unable to read column %s\n", xSigmaName);
670 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
671 }
672 sy0 = NULL;
674 fprintf(stderr, "error: unable to read column %s\n", ySigmaName);
676 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
677 }
678 if (!sy0)
679 sy0 =
tmalloc(
sizeof(*sy0) * points);
680
681 if (xMin != xMax || sparseInterval != 1) {
682 xOrig =
tmalloc(
sizeof(*xOrig) * points);
683 yOrig =
tmalloc(
sizeof(*yOrig) * points);
684 if (sx)
685 sxOrig =
tmalloc(
sizeof(*sxOrig) * points);
686 if (ySigmasValid)
687 syOrig =
tmalloc(
sizeof(*syOrig) * points);
688 pointsOrig = points;
689 for (i = j = 0; i < points; i++) {
690 xOrig[i] = x[i];
691 yOrig[i] = y[i];
692 if (ySigmasValid)
693 syOrig[i] = sy0[i];
694 if (sx)
695 sxOrig[i] = sx[i];
696 }
697 if (xMin != xMax) {
698 for (i = j = 0; i < points; i++) {
699 if (xOrig[i] <= xMax && xOrig[i] >= xMin) {
700 x[j] = xOrig[i];
701 y[j] = yOrig[i];
702 if (ySigmasValid)
703 sy0[j] = syOrig[i];
704 if (sx)
705 sx[j] = sxOrig[i];
706 j++;
707 }
708 }
709 points = j;
710 }
711 if (sparseInterval != 1) {
712 for (i = j = 0; i < points; i++) {
713 if (i % sparseInterval == 0) {
714 x[j] = x[i];
715 y[j] = y[i];
716 if (ySigmasValid)
717 sy0[j] = sy0[i];
718 if (sx)
719 sx[j] = sx[i];
720 j++;
721 }
722 }
723 points = j;
724 }
725 } else {
726 xOrig = x;
727 yOrig = y;
728 sxOrig = sx;
729 syOrig = sy0;
730 pointsOrig = points;
731 }
732
734
735 if (sigmasMode == ABSOLUTE_SIGMAS) {
736 for (i = 0; i < points; i++)
737 sy0[i] = sigmas;
738 if (sy0 != syOrig)
739 for (i = 0; i < pointsOrig; i++)
740 syOrig[i] = sigmas;
741 } else if (sigmasMode == FRACTIONAL_SIGMAS) {
742 for (i = 0; i < points; i++)
743 sy0[i] = sigmas * fabs(y[i]);
744 if (sy0 != syOrig)
745 for (i = 0; i < pointsOrig; i++)
746 syOrig[i] = fabs(yOrig[i]) * sigmas;
747 }
748
749 if (!ySigmasValid || generateSigmas)
750 for (i = 0; i < points; i++)
751 sy0[i] = 1;
752 else
753 for (i = 0; i < points; i++)
754 if (sy0[i] == 0)
755 SDDS_Bomb(
"y sigma = 0 for one or more points.");
756
757 diff =
tmalloc(
sizeof(*x) * points);
758 sy =
tmalloc(
sizeof(*sy) * points);
759 for (i = 0; i < points; i++)
760 sy[i] = sy0[i];
761
763 xOffset = 0;
764
767 if (chebyshev) {
768 if (xOffset) {
769
770 xScaleFactor = MAX(fabs(xHigh - xOffset), fabs(xLow - xOffset));
771 } else {
772
773 xOffset = (xHigh + xLow) / 2;
774 xScaleFactor = (xHigh - xLow) / 2;
775 }
778 }
779
780 if (generateSigmas || modifySigmas) {
781
782 isFit =
lsfg(x, y, sy, points, terms, order, coef, coefSigma, &chi,
783 diff, basis_fn);
784 if (!isFit)
786 if (verbose) {
787 fputs("initial_fit:", stdout);
788 print_coefs(stdout, xOffset, xScaleFactor, chebyshev, coef, NULL,
789 order, terms, chi, normTerm, "");
790 fprintf(stdout, "unweighted rms deviation from fit: %21.15e\n",
791 rms_average(diff, points));
792 }
793 if (modifySigmas) {
794 if (!ySigmasValid) {
795 for (i = 0; i < points; i++)
796 sy[i] =
797 fabs(
eval_sum(basis_dfn, coef, order, terms, x[i]) * sx[i]);
798 } else
799 for (i = 0; i < points; i++) {
800 sy[i] = sqrt(
801 sqr(sy0[i]) +
802 sqr(
eval_sum(basis_dfn, coef, order, terms, x[i]) * sx[i]));
803 }
804 }
805 if (generateSigmas) {
806 double sigma;
807 for (i = sigma = 0; i < points; i++) {
808 sigma += sqr(diff[i]);
809 }
810 sigma = sqrt(sigma / (points - terms));
811 for (i = 0; i < points; i++) {
812 if (generateSigmas & FLGS_KEEPSMALLEST) {
813 if (sigma < sy[i])
814 sy[i] = sigma;
815 } else if (generateSigmas & FLGS_KEEPLARGEST) {
816 if (sigma > sy[i])
817 sy[i] = sigma;
818 } else {
819 sy[i] = sigma;
820 }
821 }
822 for (i = 0; i < pointsOrig; i++) {
823 if (generateSigmas & FLGS_KEEPSMALLEST) {
824 if (sigma < sy0[i])
825 sy0[i] = sigma;
826 } else if (generateSigmas & FLGS_KEEPLARGEST) {
827 if (sigma > sy0[i])
828 sy0[i] = sigma;
829 } else {
830 sy0[i] = sigma;
831 }
832 }
833 }
834 }
835
836 if (reviseOrders & REVPOW_ACTIVE) {
837 terms = reviseFitOrders(
838 x, y, sy, points, terms, order, coef, coefSigma, diff, basis_fn,
839 reviseOrders, xOffset, xScaleFactor, normTerm, ySigmasValid,
840 chebyshev, revpowThreshold, revpowCompleteThres, goodEnoughChi);
841 reviseOrders = 0;
842 }
843
844 if (repeatFits <= 1) {
845 isFit =
lsfg(x, y, sy, points, terms, order, coef, coefSigma, &chi, diff,
846 basis_fn);
847 } else {
848 double *coefRepeat =
tmalloc(
sizeof(*coefRepeat) * terms * repeatFits);
849 double *coefSigmaRepeat =
tmalloc(
sizeof(*coefSigmaRepeat) * terms * repeatFits);
850 long fitIdx;
851 isFit = 1;
852 srand(1);
853 for (fitIdx = 0; fitIdx < repeatFits; fitIdx++) {
854
855 int64_t *indices =
tmalloc(
sizeof(*indices) * points);
856 for (i = 0; i < points; i++) indices[i] = rand() % points;
857 double *xSample =
tmalloc(
sizeof(*xSample) * points);
858 double *ySample =
tmalloc(
sizeof(*ySample) * points);
859 double *sySample =
tmalloc(
sizeof(*sySample) * points);
860 for (i = 0; i < points; i++) {
861 xSample[i] = x[indices[i]];
862 ySample[i] = y[indices[i]];
863 sySample[i] = sy[i];
864 }
865 double chiTmp;
866 double *diffTmp =
tmalloc(
sizeof(*diffTmp) * points);
867 int fitOk =
lsfg(xSample, ySample, sySample, points, terms, order, coefRepeat + fitIdx * terms, coefSigmaRepeat + fitIdx * terms, &chiTmp, diffTmp, basis_fn);
868 free(indices);
869 free(xSample);
870 free(ySample);
871 free(sySample);
872 free(diffTmp);
873 isFit *= fitOk;
874 }
875
876 for (i = 0; i < terms; i++) {
877 double sum = 0, sum2 = 0;
878 for (j = 0; j < repeatFits; j++) {
879 double v = coefRepeat[j * terms + i];
880 sum += v;
881 sum2 += v * v;
882 }
883 coef[i] = sum / repeatFits;
884 coefSigma[i] = sqrt(sum2 / repeatFits - (coef[i] * coef[i]));
885 }
886 free(coefRepeat);
887 free(coefSigmaRepeat);
888
889 chi = 0;
890 for (i = 0; i < points; i++) {
891 double fitValue =
eval_sum(basis_fn, coef, order, terms, x[i]);
892 diff[i] = fitValue- y[i];
893 chi += sqr(diff[i]);
894 }
895 chi /= points - terms;
896 }
897 if (isFit) {
898 rmsResidual = rms_average(diff, points);
899 if (verbose) {
900 print_coefs(stdout, xOffset, xScaleFactor, chebyshev, coef,
901 (ySigmasValid ? coefSigma : NULL), order, terms, chi,
902 normTerm, "");
903 fprintf(stdout, "unweighted rms deviation from fit: %21.15e\n",
904 rmsResidual);
905 }
906 } else if (verbose)
907 fprintf(stdout, "fit failed.\n");
908
909 if (evalParameters.file)
910 makeEvaluationTable(&evalParameters, x, points, coef, order, terms,
911 &SDDSin, xName, yName);
912 }
913
914 if (!
SDDS_StartPage(&SDDSout, rangeFitOnly ? pointsOrig : points))
916 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
917 rpnSeqBuffer[0] = 0;
918 if (!invalid) {
919 setCoefficientData(&SDDSout, coef, ((repeatFits || ySigmasValid) ? coefSigma : NULL),
920 coefUnits, order, terms, chebyshev, fitLabelFormat,
921 rpnSeqBuffer);
922 if (rangeFitOnly) {
923 double *residual;
924 compareOriginalToFit(xOrig, yOrig, &residual, pointsOrig, &rmsResidual,
925 coef, order, terms);
926
928 pointsOrig, ix) ||
930 pointsOrig, iy) ||
932 pointsOrig, iResidual))
934 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
935 for (i = 0; i < pointsOrig; i++)
936 residual[i] = yOrig[i] - residual[i];
937
939 pointsOrig, iFit))
941 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
942
943 if (ixSigma != -1 &&
945 pointsOrig, ixSigma))
947 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
948 if (ySigmasValid && iySigma != -1 &&
950 pointsOrig, iySigma))
952 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
953 free(residual);
954 } else {
955 for (i = 0; i < points; i++)
956 diff[i] =
957 -diff[i];
959 ix) ||
961 iy) ||
963 points, iResidual))
965 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
966 for (i = 0; i < points; i++)
967 diff[i] =
968 y[i] - diff[i];
970 points, iFit))
972 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
973
974 if (ixSigma != -1 &&
976 ixSigma))
978 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
979 if (ySigmasValid && iySigma != -1 &&
981 iySigma))
983 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
984 }
985 }
986
989 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
991 &SDDSout, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, iRpnSequence,
992 invalid ? "" : rpnSeqBuffer, iRmsResidual,
993 invalid ? NaN : rmsResidual, iChiSq, invalid ? NaN : chi, iTerms,
994 terms, iSigLevel,
996 invalid ? NaN : xOffset, iFactor, invalid ? NaN : xScaleFactor,
997 iFitIsValid, isFit ? 'y' : 'n', -1) ||
1000 SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1001 if (!invalid) {
1002 free(diff);
1003 free(sy);
1004 if (xOrig != x)
1005 free(xOrig);
1006 if (yOrig != y)
1007 free(yOrig);
1008 if (syOrig != sy0)
1009 free(syOrig);
1010 if (sxOrig != sx)
1011 free(sxOrig);
1012 free(x);
1013 free(y);
1014 free(sx);
1015 free(sy0);
1016 }
1017 }
1020 exit(EXIT_FAILURE);
1021 }
1022 if (evalParameters.initialized && !
SDDS_Terminate(&(evalParameters.dataset)))
1023 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1024
1025 free(coef);
1026 free(coefSigma);
1027 if (coefUnits)
1028 free(coefUnits);
1029 if (order)
1030 free(order);
1031
1032 return (EXIT_SUCCESS);
1033}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
long lsfg(double *xd, double *yd, double *sy, long n_pts, long n_terms, int32_t *order, double *coef, double *s_coef, double *chi, double *diff, double(*fn)(double x, long ord))
Computes generalized least squares fits using a function passed by the caller.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
void set_argument_scale(double scale)
Set the scale factor applied to the input argument of basis functions.
void set_argument_offset(double offset)
Set the offset applied to the input argument of basis functions.
double dtcheby(double x, long n)
Evaluate the derivative of the Chebyshev polynomial T_n(x).
double ipower(double x, long n)
Evaluate a power function x^n.
double dipower(double x, long n)
Evaluate the derivative of x^n.
double tcheby(double x, long n)
Evaluate the Chebyshev polynomial of the first kind T_n(x).
double ChiSqrSigLevel(double ChiSquared0, long nu)
Computes the probability that a chi-squared variable exceeds a given value.
char * str_tolower(char *s)
Convert a string to lower case.