GIRAFFE Pipeline Reference Manual

gimodel.c
1 /*
2  * This file is part of the GIRAFFE Pipeline
3  * Copyright (C) 2002-2019 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23 
24 #include <math.h>
25 #include <string.h>
26 
27 #include <cxtypes.h>
28 #include <cxmemory.h>
29 #include <cxmessages.h>
30 #include <cxstrutils.h>
31 
32 #include <cpl_error.h>
33 
34 #include "gierror.h"
35 #include "gimodels.h"
36 
37 
46 inline static void
47 _giraffe_model_set_flag(GiModel *self, cxint idx, cxbool value)
48 {
49 
50  cx_assert(self != NULL);
51 
52  if (self->parameters.flags == NULL) {
53  self->parameters.flags = cx_calloc(self->parameters.count,
54  sizeof(cxint));
55  }
56 
57  if (value == TRUE) {
58  if (self->parameters.flags[idx] == 0) {
59  self->parameters.flags[idx] = 1;
60  self->fit.nfree += 1;
61  }
62  }
63  else {
64  if (self->parameters.flags[idx] == 1) {
65  self->parameters.flags[idx] = 0;
66  self->fit.nfree -= 1;
67  }
68  }
69 
70  return;
71 
72 }
73 
74 
75 inline static cxbool
76 _giraffe_model_get_flag(const GiModel *self, cxint idx)
77 {
78 
79  cx_assert(self != NULL);
80 
81  if (self->parameters.flags == NULL) {
82  return FALSE;
83  }
84 
85  return self->parameters.flags[idx] == 0 ? FALSE : TRUE;
86 
87 }
88 
89 
90 inline static cxdouble
91 _giraffe_compute_rsquare(cxdouble rss, cpl_matrix *y, cxint n)
92 {
93 
94  register cxint i;
95 
96  register cxdouble my = 0.;
97  register cxdouble sy = 0.;
98  register cxdouble ss = 0.;
99 
100  cxdouble r = 0.;
101  cxdouble *_y = cpl_matrix_get_data(y);
102 
103 
104  if (n < 1) {
105  return 0.;
106  }
107 
108  for (i = 0; i < n; i++) {
109  my += _y[i];
110  }
111  my /= n;
112 
113 
114  for (i = 0; i < n; i++) {
115  sy = _y[i] - my;
116  ss += sy * sy;
117  }
118 
119  r = rss / ss;
120 
121  if (isnan(r)) {
122  return 0.;
123  }
124 
125  return 1. - r;
126 
127 }
128 
129 
130 inline static cxint
131 _giraffe_model_fit(GiModel *self, cpl_matrix *x, cpl_matrix *y,
132  cpl_matrix *sigma, cxint ndata, cxint start,
133  cxint stride)
134 {
135 
136  cxint status = 0;
137 
138  cxdouble _chisq = 0.;
139 
140  GiFitParams setup;
141 
142 
143  if ((cpl_matrix_get_nrow(x) != cpl_matrix_get_nrow(y)) ||
144  (cpl_matrix_get_nrow(x) != cpl_matrix_get_nrow(sigma))) {
145  return -128;
146  }
147 
148  if (cpl_matrix_get_ncol(x) != self->arguments.count) {
149  return -128;
150  }
151 
152 
153  /*
154  * Check data selection range
155  */
156 
157  if (cpl_matrix_get_nrow(y) <= start + stride * (ndata - 1)) {
158  return -255;
159  }
160 
161 
162  /*
163  * Setup the fit
164  */
165 
166  setup.iterations = self->fit.setup.iterations;
167  setup.tests = self->fit.setup.tests;
168  setup.dchisq = self->fit.setup.delta;
169 
170  if (self->fit.covariance != NULL) {
171  cpl_matrix_set_size(self->fit.covariance, self->parameters.count,
172  self->parameters.count);
173  cpl_matrix_fill(self->fit.covariance, 0.);
174  }
175  else {
176  self->fit.covariance = cpl_matrix_new(self->parameters.count,
177  self->parameters.count);
178  }
179 
180 
181  /*
182  * Fit the data
183  */
184 
185  giraffe_error_push();
186 
187  status = giraffe_nlfit(x, y, sigma, ndata, self->parameters.values,
188  self->parameters.limits, self->parameters.flags,
189  self->parameters.count, self->fit.covariance,
190  &_chisq, self->model, &setup);
191 
192  if (status < 0) {
193 
194  if (cpl_error_get_code() == CPL_ERROR_NONE) {
195  giraffe_error_pop();
196  }
197 
198  return status;
199 
200  }
201 
202  if (cpl_error_get_code() != CPL_ERROR_NONE) {
203  return -255;
204  }
205 
206  giraffe_error_pop();
207 
208  self->fit.df = ndata - self->fit.nfree;
209  self->fit.iterations = status;
210  self->fit.chisq = _chisq;
211  self->fit.rsquare = _giraffe_compute_rsquare(self->fit.chisq, y, ndata);
212 
213  return 0;
214 
215 }
216 
217 
218 GiModel *
219 giraffe_model_new(const cxchar *name)
220 {
221 
222  register cxint i = 0;
223 
224  GiModel *self = NULL;
225 
226 
227  if (name == NULL) {
228  return NULL;
229  }
230 
231  while (giraffe_models[i].name != NULL) {
232 
233  if (strcmp(name, giraffe_models[i].name) == 0) {
234 
235  self = cx_calloc(1, sizeof(GiModel));
236 
237  giraffe_error_push();
238 
239  giraffe_models[i].ctor(self, &giraffe_models[i]);
240 
241  if (cpl_error_get_code() != CPL_ERROR_NONE) {
242 
243  giraffe_model_delete(self);
244  self = NULL;
245 
246  break;
247 
248  }
249 
250  break;
251 
252  }
253 
254  ++i;
255 
256  }
257 
258  self->fit.setup.iterations = 0;
259  self->fit.setup.tests = 0;
260  self->fit.setup.delta = 0.;
261 
262  self->fit.iterations = 0;
263  self->fit.nfree = 0;
264  self->fit.df = 0;
265  self->fit.covariance = NULL;
266 
267  return self;
268 
269 }
270 
271 
272 GiModel *
273 giraffe_model_clone(const GiModel *other)
274 {
275 
276  GiModel *self = NULL;
277 
278 
279  if (other != NULL) {
280 
281  self = giraffe_model_new(other->name);
282 
283  /*
284  * The model constructor creates already an a property list and
285  * a matrix as container for the argument and parameter names and
286  * values. We get rid of them here before we create the copies.
287  * This way is simpler than copying each argument and parameter
288  * individually.
289  */
290 
291  cpl_propertylist_delete(self->arguments.names);
292  self->arguments.names =
293  cpl_propertylist_duplicate(other->arguments.names);
294 
295  cpl_matrix_delete(self->arguments.values);
296  self->arguments.values =
297  cpl_matrix_duplicate(other->arguments.values);
298 
299  self->arguments.count = other->arguments.count;
300 
301  cx_assert(cpl_propertylist_get_size(self->arguments.names) ==
302  self->arguments.count);
303  cx_assert(cpl_matrix_get_nrow(self->arguments.values) *
304  cpl_matrix_get_ncol(self->arguments.values) ==
305  self->arguments.count);
306 
307 
308  cpl_propertylist_delete(self->parameters.names);
309  self->parameters.names =
310  cpl_propertylist_duplicate(other->parameters.names);
311 
312  cpl_matrix_delete(self->parameters.values);
313  self->parameters.values =
314  cpl_matrix_duplicate(other->parameters.values);
315 
316  self->parameters.count = other->parameters.count;
317 
318  cx_assert(cpl_propertylist_get_size(self->parameters.names) ==
319  self->parameters.count);
320  cx_assert(cpl_matrix_get_nrow(self->parameters.values) *
321  cpl_matrix_get_ncol(self->parameters.values) ==
322  self->parameters.count);
323 
324  self->fit.setup = other->fit.setup;
325  self->fit.iterations = other->fit.iterations;
326  self->fit.nfree = other->fit.nfree;
327  self->fit.df = other->fit.df;
328 
329  if (other->fit.covariance == NULL) {
330  self->fit.covariance = NULL;
331  }
332  else {
333  self->fit.covariance =
334  cpl_matrix_duplicate(other->fit.covariance);
335  }
336 
337  }
338 
339  return self;
340 
341 }
342 
343 void
344 giraffe_model_delete(GiModel *self)
345 {
346 
347  if (self) {
348 
349  register cxint i = 0;
350 
351  while (giraffe_models[i].name != NULL) {
352 
353  if (strcmp(self->name, giraffe_models[i].name) == 0) {
354  giraffe_models[i].dtor(self);
355  cx_free(self);
356 
357  break;
358  }
359 
360  ++i;
361 
362  }
363 
364  }
365 
366  return;
367 
368 }
369 
370 
371 const cxchar *
372 giraffe_model_get_name(const GiModel *self)
373 {
374 
375  cx_assert(self != NULL);
376  return self->name;
377 
378 }
379 
380 
381 GiModelType
382 giraffe_model_get_type(const GiModel *self)
383 {
384 
385  cx_assert(self != NULL);
386  return self->type;
387 
388 }
389 
390 
391 cxsize
392 giraffe_model_count_arguments(const GiModel *self)
393 {
394 
395  cx_assert(self != NULL);
396  return self->arguments.count;
397 
398 }
399 
400 
401 cxsize
402 giraffe_model_count_parameters(const GiModel *self)
403 {
404 
405  cx_assert(self != NULL);
406  return self->parameters.count;
407 
408 }
409 
410 
411 const cxchar*
412 giraffe_model_argument_name(const GiModel* self, cxsize position)
413 {
414 
415  const cpl_property* p = NULL;
416 
417 
418  cx_assert(self != NULL);
419 
420  p = cpl_propertylist_get(self->arguments.names, position);
421  if (p == NULL) {
422  return NULL;
423  }
424 
425  return cpl_property_get_name(p);
426 
427 }
428 
429 
430 const cxchar*
431 giraffe_model_parameter_name(const GiModel* self, cxsize position)
432 {
433 
434  const cpl_property* p = NULL;
435 
436 
437  cx_assert(self != NULL);
438 
439  p = cpl_propertylist_get(self->parameters.names, position);
440  if (p == NULL) {
441  return NULL;
442  }
443 
444  return cpl_property_get_name(p);
445 
446 }
447 
448 
449 cxint
450 giraffe_model_set_argument(GiModel *self, const cxchar *name, cxdouble value)
451 {
452 
453  const cxchar *const fctid = "giraffe_model_set_argument";
454 
455 
456  cx_assert(self != NULL);
457 
458  if (name == NULL) {
459  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
460  return 1;
461  }
462 
463  if (!cpl_propertylist_has(self->arguments.names, name)) {
464  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
465  return 1;
466  }
467  else {
468 
469  register cxint idx = cpl_propertylist_get_int(self->arguments.names,
470  name);
471 
472  cpl_matrix_set(self->arguments.values, idx, 0, value);
473 
474  }
475 
476  return 0;
477 
478 }
479 
480 
481 cxdouble
482 giraffe_model_get_argument(const GiModel *self, const cxchar *name)
483 {
484 
485  const cxchar *const fctid = "giraffe_model_get_argument";
486 
487  register cxint idx;
488 
489 
490  cx_assert(self != NULL);
491 
492  if (name == NULL) {
493  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
494  return 0.;
495  }
496 
497  if (!cpl_propertylist_has(self->arguments.names, name)) {
498  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
499  return 0.;
500  }
501 
502 
503  idx = cpl_propertylist_get_int(self->arguments.names, name);
504 
505  return cpl_matrix_get(self->arguments.values, idx, 0);
506 
507 }
508 
509 
510 cxint
511 giraffe_model_set_parameter(GiModel *self, const cxchar *name,
512  cxdouble value)
513 {
514 
515  const cxchar *const fctid = "giraffe_model_set_parameter";
516 
517 
518  cx_assert(self != NULL);
519 
520  if (name == NULL) {
521  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
522  return 1;
523  }
524 
525  if (!cpl_propertylist_has(self->parameters.names, name)) {
526  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
527  return 1;
528  }
529  else {
530 
531  register cxint idx = cpl_propertylist_get_int(self->parameters.names,
532  name);
533 
534  cpl_matrix_set(self->parameters.values, idx, 0, value);
535 
536  }
537 
538  return 0;
539 
540 }
541 
542 
543 cxdouble
544 giraffe_model_get_parameter(const GiModel *self, const cxchar *name)
545 {
546 
547  const cxchar *const fctid = "giraffe_model_get_parameter";
548 
549  register cxint idx;
550 
551 
552  cx_assert(self != NULL);
553 
554  if (name == NULL) {
555  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
556  return 0.;
557  }
558 
559  if (!cpl_propertylist_has(self->parameters.names, name)) {
560  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
561  return 0.;
562  }
563 
564 
565  idx = cpl_propertylist_get_int(self->parameters.names, name);
566 
567  return cpl_matrix_get(self->parameters.values, idx, 0);
568 
569 }
570 
571 
572 cxint
573 giraffe_model_freeze_parameter(GiModel *self, const cxchar *name)
574 {
575 
576  const cxchar *const fctid = "giraffe_model_freeze_parameter";
577 
578 
579  if (self == NULL) {
580  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
581  return 1;
582  }
583 
584  if (name == NULL) {
585  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
586  return 1;
587  }
588 
589  if (!cpl_propertylist_has(self->parameters.names, name)) {
590  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
591  return 1;
592  }
593  else {
594 
595  register cxint idx = cpl_propertylist_get_int(self->parameters.names,
596  name);
597 
598  _giraffe_model_set_flag(self, idx, FALSE);
599 
600  }
601 
602  return 0;
603 
604 }
605 
606 
607 cxint
608 giraffe_model_thaw_parameter(GiModel *self, const cxchar *name)
609 {
610 
611  const cxchar *const fctid = "giraffe_model_thaw_parameter";
612 
613 
614  cx_assert(self != NULL);
615 
616  if (name == NULL) {
617  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
618  return 1;
619  }
620 
621  if (!cpl_propertylist_has(self->parameters.names, name)) {
622  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
623  return 1;
624  }
625  else {
626 
627  register cxint idx = cpl_propertylist_get_int(self->parameters.names,
628  name);
629 
630  _giraffe_model_set_flag(self, idx, TRUE);
631 
632  }
633 
634  return 0;
635 
636 }
637 
638 
639 cxbool
640 giraffe_model_frozen_parameter(const GiModel *self, const cxchar *name)
641 {
642 
643  const cxchar *const fctid = "giraffe_model_frozen_parameter";
644 
645  register cxint idx;
646 
647 
648  cx_assert(self != NULL);
649 
650  if (name == NULL) {
651  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
652  return FALSE;
653  }
654 
655  if (!cpl_propertylist_has(self->parameters.names, name)) {
656  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
657  return FALSE;
658  }
659 
660 
661  idx = cpl_propertylist_get_int(self->parameters.names, name);
662 
663  return _giraffe_model_get_flag(self, idx) == FALSE;
664 
665 }
666 
667 
668 cxint
669 giraffe_model_freeze(GiModel *self)
670 {
671 
672  register cxint i;
673 
674 
675  cx_assert(self != NULL);
676 
677  for (i = 0; i < cpl_propertylist_get_size(self->parameters.names); i++) {
678 
679  const cpl_property *p = cpl_propertylist_get(self->parameters.names,
680  i);
681 
682  if (p == NULL) {
683  return 1;
684  }
685 
686  _giraffe_model_set_flag(self, cpl_property_get_int(p), FALSE);
687 
688  }
689 
690  return 0;
691 
692 }
693 
694 
695 cxint
696 giraffe_model_thaw(GiModel *self)
697 {
698 
699  register cxint i;
700 
701 
702  cx_assert(self != NULL);
703 
704  for (i = 0; i < cpl_propertylist_get_size(self->parameters.names); i++) {
705 
706  const cpl_property *p = cpl_propertylist_get(self->parameters.names,
707  i);
708 
709  if (p == NULL) {
710  return 1;
711  }
712 
713  _giraffe_model_set_flag(self, cpl_property_get_int(p), TRUE);
714 
715  }
716 
717  return 0;
718 
719 }
720 
721 
722 cxint
723 giraffe_model_evaluate(const GiModel *self, cxdouble *result, cxint *status)
724 {
725 
726  const cxchar *const fctid = "giraffe_model_evaluate";
727 
728  cxdouble _result = 0.;
729  cxdouble *arg = NULL;
730  cxdouble *par = NULL;
731 
732 
733  cx_assert(self != NULL);
734 
735  arg = cpl_matrix_get_data(self->arguments.values);
736 
737  if (arg == NULL) {
738  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
739  return 2;
740  }
741 
742  par = cpl_matrix_get_data(self->parameters.values);
743 
744  if (par == NULL) {
745  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
746  return 3;
747  }
748 
749  giraffe_error_push();
750 
751  self->model(&_result, arg, par, self->parameters.count, NULL, NULL);
752 
753  if (cpl_error_get_code() != CPL_ERROR_NONE) {
754 
755  if (status) {
756  *status = 1;
757  }
758 
759  return 4;
760 
761  }
762 
763  giraffe_error_pop();
764 
765  *result = _result;
766  *status = 0;
767 
768  return 0;
769 
770 }
771 
772 
773 cxint
774 giraffe_model_set_iterations(GiModel *self, cxint iterations)
775 {
776 
777  cx_assert(self != NULL);
778 
779  if (iterations < 1) {
780  return 1;
781  }
782 
783  self->fit.setup.iterations = iterations;
784 
785  return 0;
786 
787 }
788 
789 
790 cxint
791 giraffe_model_get_iterations(const GiModel *self)
792 {
793 
794  cx_assert(self != NULL);
795 
796  return self->fit.setup.iterations;
797 
798 }
799 
800 
801 cxint
802 giraffe_model_set_tests(GiModel *self, cxint tests)
803 {
804 
805  cx_assert(self != NULL);
806 
807  if (tests < 1) {
808  return 1;
809  }
810 
811  self->fit.setup.tests = tests;
812 
813  return 0;
814 
815 }
816 
817 
818 cxint
819 giraffe_model_get_tests(const GiModel *self)
820 {
821 
822  cx_assert(self != NULL);
823 
824  return self->fit.setup.tests;
825 
826 }
827 
828 
829 cxint
830 giraffe_model_set_delta(GiModel *self, cxdouble delta)
831 {
832 
833  cx_assert(self != NULL);
834 
835  if (delta < 0.) {
836  return 1;
837  }
838 
839  self->fit.setup.delta = delta;
840 
841  return 0;
842 
843 }
844 
845 
846 cxdouble
847 giraffe_model_get_delta(const GiModel *self)
848 {
849 
850  cx_assert(self != NULL);
851 
852  return self->fit.setup.delta;
853 
854 }
855 
856 
857 cxint
858 giraffe_model_get_position(const GiModel *self)
859 {
860 
861  cx_assert(self != NULL);
862 
863  if (self->fit.iterations <= 0) {
864  return -1;
865  }
866 
867  return self->fit.iterations;
868 
869 }
870 
871 
872 cxdouble
873 giraffe_model_get_variance(const GiModel *self, const cxchar *name)
874 {
875 
876  const cxchar *const fctid = "giraffe_model_get_variance";
877 
878 
879  cxdouble variance = 0.;
880 
881 
882  cx_assert(self != NULL);
883 
884  if (name == NULL) {
885  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
886  return variance;
887  }
888 
889  if (!cpl_propertylist_has(self->parameters.names, name)) {
890  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
891  return variance;
892  }
893  else {
894 
895  if (self->fit.covariance == NULL) {
896  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
897  return variance;
898  }
899  else {
900 
901  register cxint idx =
902  cpl_propertylist_get_int(self->parameters.names, name);
903 
904  variance = cpl_matrix_get(self->fit.covariance, idx, idx);
905 
906  }
907 
908  }
909 
910  return variance;
911 
912 }
913 
914 
915 cxdouble
916 giraffe_model_get_sigma(const GiModel *self, const cxchar *name)
917 {
918 
919  const cxchar *const fctid = "giraffe_model_get_sigma";
920 
921 
922  cxdouble sigma = 0.;
923 
924 
925  cx_assert(self != NULL);
926 
927  if (name == NULL) {
928  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
929  return sigma;
930  }
931 
932  if (!cpl_propertylist_has(self->parameters.names, name)) {
933  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
934  return sigma;
935  }
936  else {
937 
938  if (self->fit.covariance == NULL) {
939  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
940  return sigma;
941  }
942  else {
943 
944  register cxint idx =
945  cpl_propertylist_get_int(self->parameters.names, name);
946 
947  sigma = cpl_matrix_get(self->fit.covariance, idx, idx);
948 
949  if (isnan(sigma) || sigma < 0.) {
950  sigma = 0.;
951  }
952  else {
953  sigma = sqrt(sigma);
954  }
955 
956  }
957 
958  }
959 
960  return sigma;
961 
962 }
963 
964 
965 cxint
966 giraffe_model_get_df(const GiModel *self)
967 {
968 
969  cx_assert(self != NULL);
970 
971  return self->fit.df;
972 
973 }
974 
975 
976 cxdouble
977 giraffe_model_get_chisq(const GiModel *self)
978 {
979 
980  cx_assert(self != NULL);
981 
982  return self->fit.chisq;
983 
984 }
985 
986 
987 cxdouble
988 giraffe_model_get_rsquare(const GiModel *self)
989 {
990 
991  cx_assert(self != NULL);
992 
993  return self->fit.rsquare;
994 
995 }
996 
997 
998 cxint
999 giraffe_model_fit(GiModel *self, cpl_matrix *x, cpl_matrix *y,
1000  cpl_matrix *sigma)
1001 {
1002 
1003  cxint ndata = 0;
1004 
1005 
1006  cx_assert(self != NULL);
1007 
1008  if (x == NULL || y == NULL) {
1009  return -128;
1010  }
1011 
1012  if (sigma == NULL) {
1013  return -128;
1014  }
1015 
1016  ndata = cpl_matrix_get_nrow(y);
1017 
1018  return _giraffe_model_fit(self, x, y, sigma, ndata, 0, 1);
1019 
1020 }
1021 
1022 
1023 cxint
1024 giraffe_model_fit_sequence(GiModel *self, cpl_matrix *x, cpl_matrix *y,
1025  cpl_matrix *sigma, cxint ndata, cxint start,
1026  cxint stride)
1027 {
1028 
1029  cx_assert(self != NULL);
1030 
1031  /* FIXME: Currently only (start == 0 && stride == 1) is supported! */
1032  cx_assert((start == 0) || (stride == 1));
1033 
1034 
1035  if (x == NULL || y == NULL) {
1036  return -128;
1037  }
1038 
1039  if (sigma == NULL) {
1040  return -128;
1041  }
1042 
1043  if ((start < 0) || (stride < 0)) {
1044  return -128;
1045  }
1046 
1047  return _giraffe_model_fit(self, x, y, sigma, ndata, 0, 1);
1048 
1049 }
cxint giraffe_nlfit(cpl_matrix *x, cpl_matrix *y, cpl_matrix *sigma, cxint ndata, cpl_matrix *a, cpl_matrix *delta, cxint *ia, cxint ma, cpl_matrix *alpha, cxdouble *chisq, GiFitFunc funcs, const GiFitParams *setup)
Levenberg-Marquardt non-linear fit driver.
Definition: gilevenberg.c:488
Non-linear fit control parameters.
Definition: gilevenberg.h:39
cxint iterations
Definition: gilevenberg.h:45
cxdouble dchisq
Definition: gilevenberg.h:56
cxint tests
Definition: gilevenberg.h:51

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004