1 | #include <stdlib.h>
|
---|
2 | #include <unistd.h>
|
---|
3 | #include <stdio.h>
|
---|
4 | #include <math.h>
|
---|
5 |
|
---|
6 |
|
---|
7 | #include "matxop.h"
|
---|
8 | #include "nbmath.h"
|
---|
9 |
|
---|
10 | /* Fonctions de manipulation de matrices et de vecteurs */
|
---|
11 | /* Resolution de systemes lineaires */
|
---|
12 |
|
---|
13 | /* R. Ansari Juillet 1993 */
|
---|
14 | /* LaSilla (Chili) */
|
---|
15 |
|
---|
16 |
|
---|
17 | #define MXXFLOAT 1.e36
|
---|
18 |
|
---|
19 |
|
---|
20 |
|
---|
21 | /* Nouvelle-Fonction */
|
---|
22 |
|
---|
23 | int IVecxVec(int *v1, int *v2, int n)
|
---|
24 |
|
---|
25 | /* Produit scalaire de deux vecteurs entiers */
|
---|
26 | /* Retour (int) = v1(n) . v2(n) */
|
---|
27 |
|
---|
28 | {
|
---|
29 | register int i,rc;
|
---|
30 | register int *ip1, *ip2;
|
---|
31 |
|
---|
32 | ip1 = v1; ip2 = v2;
|
---|
33 | rc = 0;
|
---|
34 | /* for(i=0; i<n; i++) rc += *(ip1+i) * *(ip2+i); */
|
---|
35 | for(i=0; i<n; i++) rc += *ip1++ * *ip2++;
|
---|
36 | return(rc);
|
---|
37 | }
|
---|
38 |
|
---|
39 |
|
---|
40 | /* Nouvelle-Fonction */
|
---|
41 |
|
---|
42 | float RVecxVec(float *v1, float *v2, int n)
|
---|
43 |
|
---|
44 | /* Produit scalaire de deux vecteurs reels */
|
---|
45 | /* Retour (float) = v1(n) . v2(n) */
|
---|
46 |
|
---|
47 | {
|
---|
48 | register int i;
|
---|
49 | register float rc;
|
---|
50 | register float *fp1, *fp2;
|
---|
51 |
|
---|
52 | fp1 = v1; fp2 = v2;
|
---|
53 | rc = 0.0;
|
---|
54 | /* for(i=0; i<n; i++) rc += *(fp1+i) * *(fp2+i); */
|
---|
55 | for(i=0; i<n; i++) rc += *fp1++ * *fp2++;
|
---|
56 | return(rc);
|
---|
57 | }
|
---|
58 |
|
---|
59 |
|
---|
60 | /* Nouvelle-Fonction */
|
---|
61 |
|
---|
62 | double DVecxVec(double *v1, double *v2, int n)
|
---|
63 |
|
---|
64 | /* Produit scalaire de deux vecteurs double */
|
---|
65 | /* Retour (float) = v1(n) . v2(n) */
|
---|
66 |
|
---|
67 | {
|
---|
68 | register int i;
|
---|
69 | register double rc;
|
---|
70 | register double *fp1, *fp2;
|
---|
71 |
|
---|
72 | fp1 = v1; fp2 = v2;
|
---|
73 | rc = 0.0;
|
---|
74 | /* for(i=0; i<n; i++) rc += *(fp1+i) * *(fp2+i); */
|
---|
75 | for(i=0; i<n; i++) rc += *fp1++ * *fp2++;
|
---|
76 | return(rc);
|
---|
77 | }
|
---|
78 |
|
---|
79 |
|
---|
80 | /* Nouvelle-Fonction */
|
---|
81 |
|
---|
82 | void IMatxVec(int *mx, int *vi, int *vo, int n)
|
---|
83 |
|
---|
84 | /* Matrice * Vecteur (Entiers) Integer */
|
---|
85 | /* Vecteur Vo(n) = Matrice Mx(n,n) . Vi(n) */
|
---|
86 |
|
---|
87 | {
|
---|
88 | register int *vp, *mxp;
|
---|
89 | register int s;
|
---|
90 | register int j,i;
|
---|
91 |
|
---|
92 | vp = vi; mxp = mx;
|
---|
93 |
|
---|
94 | for (i=0; i<n; i++)
|
---|
95 | { s = 0;
|
---|
96 | for(j=0; j<n; j++) s += *(mxp+j) * *(vp+j);
|
---|
97 | *(vo+i) = s; mxp += n; }
|
---|
98 |
|
---|
99 | return;
|
---|
100 | }
|
---|
101 |
|
---|
102 |
|
---|
103 | /* Nouvelle-Fonction */
|
---|
104 |
|
---|
105 | void RMatxVec(float *mx, float *vi, float *vo, int n)
|
---|
106 |
|
---|
107 | /* Matrice * Vecteur (Reels) float */
|
---|
108 | /* Vecteur Vo(n) = Matrice Mx(n,n) . Vi(n) */
|
---|
109 |
|
---|
110 |
|
---|
111 | /* Matrice * Vecteur (Reels) */
|
---|
112 | {
|
---|
113 | register float *vp, *mxp;
|
---|
114 | register float s;
|
---|
115 | register int j,i;
|
---|
116 |
|
---|
117 | vp = vi; mxp = mx;
|
---|
118 |
|
---|
119 | for (i=0; i<n; i++)
|
---|
120 | { s = 0;
|
---|
121 | for(j=0; j<n; j++) s += *(mxp+j) * *(vp+j);
|
---|
122 | *(vo+i) = s; mxp += n; }
|
---|
123 |
|
---|
124 | return;
|
---|
125 | }
|
---|
126 |
|
---|
127 |
|
---|
128 | /* Nouvelle-Fonction */
|
---|
129 |
|
---|
130 | void DMatxVec(double *mx, double *vi, double *vo, int n)
|
---|
131 |
|
---|
132 | /* Matrice * Vecteur (double) double */
|
---|
133 | /* Vecteur Vo(n) = Matrice Mx(n,n) . Vi(n) */
|
---|
134 |
|
---|
135 |
|
---|
136 | /* Matrice * Vecteur (Reels) */
|
---|
137 | {
|
---|
138 | register double *vp, *mxp;
|
---|
139 | register double s;
|
---|
140 | register int j,i;
|
---|
141 |
|
---|
142 | vp = vi; mxp = mx;
|
---|
143 |
|
---|
144 | for (i=0; i<n; i++)
|
---|
145 | { s = 0;
|
---|
146 | for(j=0; j<n; j++) s += *(mxp+j) * *(vp+j);
|
---|
147 | *(vo+i) = s; mxp += n; }
|
---|
148 |
|
---|
149 | return;
|
---|
150 | }
|
---|
151 |
|
---|
152 |
|
---|
153 |
|
---|
154 |
|
---|
155 | /* Nouvelle-Fonction */
|
---|
156 |
|
---|
157 | float SolveRLinSyst(float *mx, float *b, float *x, int n)
|
---|
158 |
|
---|
159 | /* Resolution de systeme lineaire */
|
---|
160 | /* Matrice Mx(n,n) * Vecteur X(n) = Vecteur B(n) */
|
---|
161 | /* Inconnu : vecteur X */
|
---|
162 | /* Retour = Determinant du systeme (=0 Pb) et X[] */
|
---|
163 | /* Note : Au retour le vecteur B(n) et la matrice Mx(n,n) */
|
---|
164 | /* sont modifies. Mx(n,n) contient une matrice triangulaire */
|
---|
165 | /* superieure */
|
---|
166 |
|
---|
167 | {
|
---|
168 | int i,k;
|
---|
169 | register int j;
|
---|
170 | register float *fp1, *fp2;
|
---|
171 | double det;
|
---|
172 | float vt1;
|
---|
173 | register float vt2;
|
---|
174 | register float six;
|
---|
175 | int pivok;
|
---|
176 |
|
---|
177 |
|
---|
178 | #define MINPIVOT 1.e-15
|
---|
179 | #define MINDETER 1.e-15
|
---|
180 |
|
---|
181 |
|
---|
182 |
|
---|
183 | for (i=0; i<n-1; i++) /* Boucle sur les pivots */
|
---|
184 | {
|
---|
185 |
|
---|
186 | /* printf("\n Iteration %d : \n",i);
|
---|
187 | for (k=0; k<n; k++)
|
---|
188 | {
|
---|
189 | for (j=0; j<n; j++) printf(" %10g ",*(mx+k*n+j));
|
---|
190 | printf(" b= %10g \n",*(b+k));
|
---|
191 | } */
|
---|
192 |
|
---|
193 | fp1 = fp2 = mx+i*n;
|
---|
194 | vt1 = *(fp1+i) ;
|
---|
195 |
|
---|
196 | if ((vt1 < MINPIVOT) && (vt1 > -MINPIVOT) ) /* Pivot trop petit */
|
---|
197 | {
|
---|
198 | pivok = 0;
|
---|
199 | for (k=i+1; k<n; k++)
|
---|
200 | {
|
---|
201 | vt1 = *(mx+k*n+i) ;
|
---|
202 | if ((vt1 > MINPIVOT) || (vt1 < -MINPIVOT) )
|
---|
203 | {
|
---|
204 | fp2 = mx+k*n;
|
---|
205 | for (j=i; j<n; j++)
|
---|
206 | {
|
---|
207 | *(fp1+j) += *(fp2+j);
|
---|
208 | }
|
---|
209 | *(b+i) += *(b+k);
|
---|
210 | vt1 = *(fp1+i) ;
|
---|
211 | fp2 = fp1;
|
---|
212 | pivok = 1;
|
---|
213 | break;
|
---|
214 | }
|
---|
215 | }
|
---|
216 | if (!pivok) return(0.0);
|
---|
217 | }
|
---|
218 |
|
---|
219 | for (k=i+1; k<n; k++)
|
---|
220 | {
|
---|
221 | fp1 += n;
|
---|
222 | vt2 = *(fp1+i) / vt1 ;
|
---|
223 | for (j=i+1; j<n; j++)
|
---|
224 | *(fp1+j) -= (vt2 * *(fp2+j));
|
---|
225 |
|
---|
226 | *(fp1+i) = 0.0;
|
---|
227 | *(b+k) -= (vt2 * *(b+i)) ;
|
---|
228 | }
|
---|
229 |
|
---|
230 | }
|
---|
231 |
|
---|
232 | /* Calcul du determinant */
|
---|
233 | det = 1.0;
|
---|
234 | for (i=0; i<n; i++) det *= *(mx+i*n+i);
|
---|
235 | if ((det < MINDETER) && (det > -MINDETER) ) return(0.0);
|
---|
236 | if (det > MXXFLOAT) det = MXXFLOAT;
|
---|
237 | if (det < -MXXFLOAT) det = -MXXFLOAT;
|
---|
238 |
|
---|
239 |
|
---|
240 | for(i=n-1; i>=0; i--)
|
---|
241 | {
|
---|
242 | fp1 = mx+i*n;
|
---|
243 | six = *(b+i);
|
---|
244 | for (j=i+1; j<n; j++) six -= (x[j] * *(fp1+j) );
|
---|
245 | x[i] = six / (*(fp1+i));
|
---|
246 |
|
---|
247 | /* printf(" Solution X[%2d] = %g \n",i,x[i]); */
|
---|
248 | }
|
---|
249 |
|
---|
250 | return(det);
|
---|
251 | }
|
---|
252 |
|
---|
253 |
|
---|
254 |
|
---|
255 |
|
---|
256 |
|
---|
257 | /* Nouvelle-Fonction */
|
---|
258 |
|
---|
259 | double SolveDLinSyst(double *mx, double *b, double *x, int n)
|
---|
260 |
|
---|
261 | /* Resolution de systeme lineaire */
|
---|
262 | /* Matrice Mx(n,n) * Vecteur X(n) = Vecteur B(n) */
|
---|
263 | /* Inconnu : vecteur X */
|
---|
264 | /* Retour = Determinant du systeme (=0 Pb) et X[] */
|
---|
265 | /* Note : Au retour le vecteur B(n) et la matrice Mx(n,n) */
|
---|
266 | /* sont modifies. Mx(n,n) contient une matrice triangulaire */
|
---|
267 | /* superieure */
|
---|
268 |
|
---|
269 | {
|
---|
270 | int i,k;
|
---|
271 | register int j;
|
---|
272 | register double *fp1, *fp2;
|
---|
273 | double det;
|
---|
274 | double vt1;
|
---|
275 | register double vt2;
|
---|
276 | register double six;
|
---|
277 | int pivok;
|
---|
278 |
|
---|
279 |
|
---|
280 | #define DMINPIVOT 1.e-25
|
---|
281 | #define DMINDETER 1.e-30
|
---|
282 |
|
---|
283 |
|
---|
284 |
|
---|
285 | for (i=0; i<n-1; i++) /* Boucle sur les pivots */
|
---|
286 | {
|
---|
287 |
|
---|
288 | /* printf("\n Iteration %d : \n",i);
|
---|
289 | for (k=0; k<n; k++)
|
---|
290 | {
|
---|
291 | for (j=0; j<n; j++) printf(" %10g ",*(mx+k*n+j));
|
---|
292 | printf(" b= %10g \n",*(b+k));
|
---|
293 | } */
|
---|
294 |
|
---|
295 | fp1 = fp2 = mx+i*n;
|
---|
296 | vt1 = *(fp1+i) ;
|
---|
297 |
|
---|
298 | if ((vt1 < DMINPIVOT) && (vt1 > -DMINPIVOT) ) /* Pivot trop petit */
|
---|
299 | {
|
---|
300 | pivok = 0;
|
---|
301 | for (k=i+1; k<n; k++)
|
---|
302 | {
|
---|
303 | vt1 = *(mx+k*n+i) ;
|
---|
304 | if ((vt1 > DMINPIVOT) || (vt1 < -DMINPIVOT) )
|
---|
305 | {
|
---|
306 | fp2 = mx+k*n;
|
---|
307 | for (j=i; j<n; j++)
|
---|
308 | {
|
---|
309 | *(fp1+j) += *(fp2+j);
|
---|
310 | }
|
---|
311 | *(b+i) += *(b+k);
|
---|
312 | vt1 = *(fp1+i) ;
|
---|
313 | fp2 = fp1;
|
---|
314 | pivok = 1;
|
---|
315 | break;
|
---|
316 | }
|
---|
317 | }
|
---|
318 | if (!pivok) return(0.0);
|
---|
319 | }
|
---|
320 |
|
---|
321 | for (k=i+1; k<n; k++)
|
---|
322 | {
|
---|
323 | fp1 += n;
|
---|
324 | vt2 = *(fp1+i) / vt1 ;
|
---|
325 | for (j=i+1; j<n; j++)
|
---|
326 | *(fp1+j) -= (vt2 * *(fp2+j));
|
---|
327 |
|
---|
328 | *(fp1+i) = 0.0;
|
---|
329 | *(b+k) -= (vt2 * *(b+i)) ;
|
---|
330 | }
|
---|
331 |
|
---|
332 | }
|
---|
333 |
|
---|
334 | /* Calcul du determinant */
|
---|
335 | det = 1.0;
|
---|
336 | for (i=0; i<n; i++) det *= *(mx+i*n+i);
|
---|
337 | if ((det < DMINDETER) && (det > -DMINDETER) ) return(0.0);
|
---|
338 | if (det > MXXFLOAT) det = MXXFLOAT;
|
---|
339 | if (det < -MXXFLOAT) det = -MXXFLOAT;
|
---|
340 |
|
---|
341 |
|
---|
342 | for(i=n-1; i>=0; i--)
|
---|
343 | {
|
---|
344 | fp1 = mx+i*n;
|
---|
345 | six = *(b+i);
|
---|
346 | for (j=i+1; j<n; j++) six -= (x[j] * *(fp1+j) );
|
---|
347 | x[i] = six / (*(fp1+i));
|
---|
348 |
|
---|
349 | /* printf(" Solution X[%2d] = %g \n",i,x[i]); */
|
---|
350 | }
|
---|
351 |
|
---|
352 | return(det);
|
---|
353 | }
|
---|
354 |
|
---|
355 |
|
---|
356 |
|
---|
357 |
|
---|
358 | /* ============================================================== */
|
---|
359 | /* Fonctions de Fit lineaire de Xi2 */
|
---|
360 | /* ============================================================== */
|
---|
361 |
|
---|
362 | /* .......... Fit avec vecteurs depart reels ............... */
|
---|
363 |
|
---|
364 | static int FFBusy = -1; /* Flag Deja Busy (GetFitVect effectue) */
|
---|
365 | static int FNVarMax = 0; /* Nb Maxi de variables a ajuster */
|
---|
366 | static int FVLenMax = 0; /* Longueur maxi des vecteurs */
|
---|
367 | static float **FVeci = NULL; /* Vecteurs en entree *Vecf = Y */
|
---|
368 | /* *(Vecf+i) = X[i] */
|
---|
369 | static float **FVecf = NULL; /* Vecteurs *FVecf = *FVecf+2 = B = M.X */
|
---|
370 | /* *(FVecf+1) = La sortie = Ai */
|
---|
371 | static float *FVSpace = NULL; /* Espace pour les *FVeci */
|
---|
372 | static float *FVSpacef = NULL; /* " " " *FVecf */
|
---|
373 | static double *FFMtx = NULL; /* Matrice a inverser = M */
|
---|
374 | static double *FFMtx2 = NULL; /* Copie de M */
|
---|
375 | static double *FFSort = NULL; /* RFitLinErr() pour Sortie GausPiv() */
|
---|
376 | /* FNVarMax Lignes * (FNVarMax+1) Col. */
|
---|
377 | /* Col1= Solution, Col2..N+1 : MatInv */
|
---|
378 |
|
---|
379 |
|
---|
380 | int InitRFitLin(int nvarmx, int szv)
|
---|
381 |
|
---|
382 | /* Initialisation du fit de Xi2 Entier */
|
---|
383 | /* Allocation d'espace memoire */
|
---|
384 | /* nvarmx = Nb maxi de variable */
|
---|
385 | /* szv = Taille maxi des vecteurs de points */
|
---|
386 |
|
---|
387 | {
|
---|
388 | int i;
|
---|
389 |
|
---|
390 | FFBusy = -1;
|
---|
391 | nvarmx ++;
|
---|
392 | if (nvarmx < 7) nvarmx = 7;
|
---|
393 | if (szv < 25) szv = 25;
|
---|
394 |
|
---|
395 | if ( (FVeci = (float**) malloc(nvarmx*sizeof(float *))) == NULL )
|
---|
396 | { printf("InitRFitLin_Erreur: (Pb malloc(Veci)) \n");
|
---|
397 | return(1);
|
---|
398 | }
|
---|
399 |
|
---|
400 | if ( (FVSpace = (float*) malloc(nvarmx*szv*sizeof(float))) == NULL )
|
---|
401 | { printf("InitRFitLin_Erreur: (Pb malloc(VSpace)) \n");
|
---|
402 | free(FVeci);
|
---|
403 | return(2);
|
---|
404 | }
|
---|
405 |
|
---|
406 | for(i=0; i<nvarmx; i++) *(FVeci+i) = FVSpace+i*szv;
|
---|
407 |
|
---|
408 |
|
---|
409 | if ( (FVecf = (float**) malloc(3*sizeof(float *))) == NULL )
|
---|
410 | { printf("InitRFitLin_Erreur: (Pb malloc(Vecf)) \n");
|
---|
411 | free(FVeci);
|
---|
412 | free(FVSpace);
|
---|
413 | return(3);
|
---|
414 | }
|
---|
415 |
|
---|
416 | if ( (FVSpacef = (float*) malloc(3*szv*sizeof(float))) == NULL )
|
---|
417 | { printf("InitRFitLin_Erreur: (Pb malloc(VSpacef)) \n");
|
---|
418 | free(FVeci);
|
---|
419 | free(FVSpace);
|
---|
420 | free(FVecf);
|
---|
421 | return(4);
|
---|
422 | }
|
---|
423 |
|
---|
424 | for(i=0; i<3; i++) *(FVecf+i) = FVSpacef+i*szv;
|
---|
425 |
|
---|
426 |
|
---|
427 | if ( (FFMtx = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
|
---|
428 | { printf("InitRFitLin_Erreur: (Pb malloc(FMtx)) \n");
|
---|
429 | free(FVeci);
|
---|
430 | free(FVSpace);
|
---|
431 | free(FVecf);
|
---|
432 | free(FVSpacef);
|
---|
433 | return(5);
|
---|
434 | }
|
---|
435 |
|
---|
436 | if ( (FFMtx2 = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
|
---|
437 | { printf("InitRFitLin_Erreur: (Pb malloc(FMtx2)) \n");
|
---|
438 | free(FVeci);
|
---|
439 | free(FVSpace);
|
---|
440 | free(FVecf);
|
---|
441 | free(FVSpacef);
|
---|
442 | free(FFMtx);
|
---|
443 | return(6);
|
---|
444 | }
|
---|
445 |
|
---|
446 | if ( (FFSort = (double*) malloc((nvarmx+1)*nvarmx*sizeof(double))) == NULL )
|
---|
447 | { printf("InitRFitLin_Erreur: (Pb malloc(FFSort)) \n");
|
---|
448 | free(FVeci);
|
---|
449 | free(FVSpace);
|
---|
450 | free(FVecf);
|
---|
451 | free(FVSpacef);
|
---|
452 | free(FFMtx);
|
---|
453 | free(FFMtx2);
|
---|
454 | return(7);
|
---|
455 | }
|
---|
456 |
|
---|
457 | FFBusy = 0;
|
---|
458 | FNVarMax = nvarmx-1;
|
---|
459 | FVLenMax = szv;
|
---|
460 |
|
---|
461 | return(0);
|
---|
462 | }
|
---|
463 |
|
---|
464 |
|
---|
465 | /* Nouvelle-Fonction */
|
---|
466 | void EndRFitLin()
|
---|
467 | {
|
---|
468 |
|
---|
469 | if (FVeci != NULL) free(FVeci);
|
---|
470 | if (FVSpace != NULL) free(FVSpace);
|
---|
471 | if (FVecf != NULL) free(FVecf);
|
---|
472 | if (FVSpacef != NULL) free(FVSpacef);
|
---|
473 | if (FFMtx != NULL) free(FFMtx);
|
---|
474 | if (FFMtx2 != NULL) free(FFMtx2);
|
---|
475 | if (FFSort != NULL) free(FFSort);
|
---|
476 |
|
---|
477 | FVeci = NULL;
|
---|
478 | FVSpace = NULL;
|
---|
479 | FVecf = NULL;
|
---|
480 | FVSpacef = NULL;
|
---|
481 | FFMtx = NULL;
|
---|
482 | FFMtx2 = NULL;
|
---|
483 |
|
---|
484 | FFBusy = -1;
|
---|
485 | FNVarMax = 0;
|
---|
486 | FVLenMax = 0;
|
---|
487 | return;
|
---|
488 | }
|
---|
489 |
|
---|
490 |
|
---|
491 | /* Nouvelle-Fonction */
|
---|
492 |
|
---|
493 | float **GetRFitVect(int nvar, int vsz)
|
---|
494 | /* reservation de l'espace des vecteurs pour le fit */
|
---|
495 | {
|
---|
496 | int nvmx, vszmx;
|
---|
497 |
|
---|
498 | if (FFBusy > 0)
|
---|
499 | { printf("GetRFitVect_Erreur: FFBusy= %d \n",FFBusy);
|
---|
500 | return(NULL); }
|
---|
501 | if ((nvar < 1) || (vsz < 1) )
|
---|
502 | { printf("GetRFitVect_Erreur: NVar,VSz= %d %d \n",nvar,vsz);
|
---|
503 | return(NULL); }
|
---|
504 | if ((nvar > FNVarMax) || (vsz > FVLenMax) || (FFBusy < 0))
|
---|
505 | {
|
---|
506 | EndRFitLin();
|
---|
507 | if (nvar > FNVarMax) nvmx = nvar;
|
---|
508 | else nvmx = FNVarMax;
|
---|
509 | if (vsz > FVLenMax) vszmx = vsz;
|
---|
510 | else vszmx = FVLenMax;
|
---|
511 | if (InitRFitLin(nvmx, vszmx) != 0) return(NULL);
|
---|
512 | }
|
---|
513 |
|
---|
514 | FFBusy = 1;
|
---|
515 | return(FVeci);
|
---|
516 | }
|
---|
517 |
|
---|
518 |
|
---|
519 | /* Nouvelle-Fonction */
|
---|
520 | void FreeRFitVect()
|
---|
521 | {
|
---|
522 | FFBusy = 0;
|
---|
523 | return;
|
---|
524 | }
|
---|
525 |
|
---|
526 | /* Nouvelle-Fonction */
|
---|
527 |
|
---|
528 | float RFitLin(int nd, int vsz, float *XVar)
|
---|
529 |
|
---|
530 | /* Effectue le fit de Xi2 pour nd inconnu, Taille vecteurs vsz */
|
---|
531 | /* Les vecteurs doivent etre remplis auparavant */
|
---|
532 | /* Retourne la valeur du Xi2 du fit, Negatif si Pb. */
|
---|
533 |
|
---|
534 | {
|
---|
535 | int i,j;
|
---|
536 | register float *ip;
|
---|
537 | register float *fp, *fp2;
|
---|
538 | register double x;
|
---|
539 | register float y;
|
---|
540 | register float *ffmtx, *ffmtx2;
|
---|
541 | float det, rc;
|
---|
542 |
|
---|
543 |
|
---|
544 | if ((nd > FNVarMax) || (vsz > FVLenMax) ) {rc = -1000.0; goto Fin; }
|
---|
545 |
|
---|
546 | /* Fabrication matrice du syteme lineaire a resoudre */
|
---|
547 | ffmtx = (float *)FFMtx;
|
---|
548 | ffmtx2 = (float *)FFMtx2;
|
---|
549 | for(i=0; i<nd; i++)
|
---|
550 | {
|
---|
551 | fp = ffmtx+i*nd; fp2 = ffmtx2+i*nd;
|
---|
552 | ip = *(FVeci+i+1);
|
---|
553 |
|
---|
554 | /* Elements diagonals */
|
---|
555 | *(fp2+i) = *(fp+i) = RVecxVec( ip, ip, vsz) ;
|
---|
556 |
|
---|
557 | for(j=i+1; j<nd; j++)
|
---|
558 | { /* Les autres elements */
|
---|
559 | *(fp2+j) = *(fp+j) = RVecxVec( ip, *(FVeci+j+1), vsz) ;
|
---|
560 | /* Matrice symetrique */
|
---|
561 | *(ffmtx2+j*nd+i) = *(ffmtx+j*nd+i) = *(fp+j);
|
---|
562 | }
|
---|
563 |
|
---|
564 | /* Second membre M.X = B */
|
---|
565 | fp = *FVecf; fp2 = *(FVecf+2);
|
---|
566 | *(fp2+i) = *(fp+i) = RVecxVec( ip, *FVeci, vsz) ;
|
---|
567 |
|
---|
568 | }
|
---|
569 |
|
---|
570 | /* On resoud le systeme lineaire : */
|
---|
571 | det = SolveRLinSyst(ffmtx, *FVecf, *(FVecf+1), nd);
|
---|
572 | if (det == 0.0) {rc = -500.0; goto Fin; }
|
---|
573 |
|
---|
574 | /* On calcule le Xi2 */
|
---|
575 | x = RVecxVec( *FVeci, *FVeci, vsz);
|
---|
576 | fp = *(FVecf+2);
|
---|
577 | for(i=0; i<nd; i++)
|
---|
578 | {
|
---|
579 | XVar[i] = y = *(*(FVecf+1)+i);
|
---|
580 | fp2 = ffmtx2+i*nd+i;
|
---|
581 | x += (y * y * *fp2);
|
---|
582 | x -= ( 2.0 * ( y * *(fp+i) ) );
|
---|
583 | for (j=i+1; j<nd; j++)
|
---|
584 | { fp2++;
|
---|
585 | x += 2.0 * y * *(*(FVecf+1)+j) * *fp2 ; }
|
---|
586 | }
|
---|
587 |
|
---|
588 | rc = (float)x;
|
---|
589 |
|
---|
590 | Fin:
|
---|
591 | FreeRFitVect();
|
---|
592 | return(rc);
|
---|
593 | }
|
---|
594 |
|
---|
595 |
|
---|
596 |
|
---|
597 | /* Nouvelle-Fonction */
|
---|
598 |
|
---|
599 | float RFitLinErr(int nd, int vsz, float *XVar, float *Err)
|
---|
600 |
|
---|
601 | /* Effectue le fit de Xi2 pour nd inconnu, Taille vecteurs vsz */
|
---|
602 | /* Les vecteurs doivent etre remplis auparavant */
|
---|
603 | /* Retourne la valeur du Xi2 du fit, Negatif si Pb. */
|
---|
604 |
|
---|
605 | {
|
---|
606 | int i,j,md;
|
---|
607 | register float *ip;
|
---|
608 | register double *dp, *dp2;
|
---|
609 | register float *fp;
|
---|
610 | register double x,y;
|
---|
611 | float rc;
|
---|
612 | double det;
|
---|
613 |
|
---|
614 |
|
---|
615 | if ((nd > FNVarMax) || (vsz > FVLenMax) ) {rc = -1000.0; goto Fin; }
|
---|
616 |
|
---|
617 | md = nd+1;
|
---|
618 | /* Mise a zero de la matrice de sortie et creation matrice identite */
|
---|
619 | for(i=0; i<nd*md; i++) FFSort[i] = 0.;
|
---|
620 | for(i=1; i<nd*md; i += md+1) FFSort[i] = 1.;
|
---|
621 |
|
---|
622 | /* Fabrication matrice du syteme lineaire a resoudre */
|
---|
623 |
|
---|
624 | for(i=0; i<nd; i++)
|
---|
625 | {
|
---|
626 | dp = FFMtx+i*nd; dp2 = FFMtx2+i*nd;
|
---|
627 | ip = *(FVeci+i+1);
|
---|
628 |
|
---|
629 | /* Elements diagonals */
|
---|
630 | *(dp+i) = *(dp2+i) = RVecxVec( ip, ip, vsz) ;
|
---|
631 |
|
---|
632 | for(j=i+1; j<nd; j++)
|
---|
633 | { /* Les autres elements */
|
---|
634 | *(dp+j) = *(dp2+j) = RVecxVec( ip, *(FVeci+j+1), vsz) ;
|
---|
635 | /* Matrice symetrique */
|
---|
636 | *(FFMtx+j*nd+i) = *(FFMtx2+j*nd+i) = *(dp+j);
|
---|
637 | }
|
---|
638 |
|
---|
639 | /* Second membre M.X = B */
|
---|
640 | dp = FFSort+i*md; fp = *(FVecf+2);
|
---|
641 | *dp = *(fp+i) = RVecxVec( ip, *FVeci, vsz) ;
|
---|
642 |
|
---|
643 | }
|
---|
644 |
|
---|
645 |
|
---|
646 | /* Appel GausPiv pour resoudre le systeme et inverser la matrice */
|
---|
647 | det = GausPiv(FFMtx, nd, nd, FFSort, md, md, 0);
|
---|
648 | /* printf("Det= %g Resul= %g %g %g \n",det,FFSort[0], FFSort[md], FFSort[2*md]); */
|
---|
649 | if (det == 0.0) {rc = -500.0; goto Fin; }
|
---|
650 |
|
---|
651 | /* On calcule le Xi2 Et remplissage vecteurs sortie */
|
---|
652 |
|
---|
653 | x = RVecxVec( *FVeci, *FVeci, vsz);
|
---|
654 | fp = *(FVecf+2);
|
---|
655 | for(i=0; i<nd; i++)
|
---|
656 | {
|
---|
657 | y = FFSort[1+i*(md+1)];
|
---|
658 | Err[i] = (y >= 0.) ? (float)sqrt(y) : -(float)sqrt(-y);
|
---|
659 | XVar[i]= y =FFSort[i*md];
|
---|
660 |
|
---|
661 | dp2 = FFMtx2+i*nd+i;
|
---|
662 | x += (y * y * *dp2);
|
---|
663 | x -= ( 2.0 * ( y * (double)*(fp+i) ) );
|
---|
664 | for (j=i+1; j<nd; j++)
|
---|
665 | { dp2++;
|
---|
666 | x += 2.0 * y * FFSort[j*md] * *dp2 ; }
|
---|
667 | }
|
---|
668 | rc = (float)x;
|
---|
669 |
|
---|
670 | Fin:
|
---|
671 | FreeRFitVect();
|
---|
672 | return(rc);
|
---|
673 | }
|
---|
674 |
|
---|
675 |
|
---|
676 |
|
---|
677 |
|
---|
678 | /* .......... Fit avec vecteurs depart double ............... */
|
---|
679 |
|
---|
680 | /* Voir description des variables ds IniRFitLin() */
|
---|
681 | static int DFBusy = -1;
|
---|
682 | static int DNVarMax = 0;
|
---|
683 | static int DVLenMax = 0;
|
---|
684 | static double **DVeci = NULL;
|
---|
685 | static double **DVecf = NULL;
|
---|
686 | static double *DVSpace = NULL;
|
---|
687 | static double *DVSpacef = NULL;
|
---|
688 | static double *DFMtx = NULL;
|
---|
689 | static double *DFMtx2 = NULL;
|
---|
690 |
|
---|
691 |
|
---|
692 | int InitDFitLin(int nvarmx, int szv)
|
---|
693 |
|
---|
694 | /* Initialisation du fit de Xi2 Entier */
|
---|
695 | /* Allocation d'espace memoire */
|
---|
696 | /* nvarmx = Nb maxi de variable */
|
---|
697 | /* szv = Taille maxi des vecteurs de points */
|
---|
698 |
|
---|
699 | {
|
---|
700 | int i;
|
---|
701 |
|
---|
702 | DFBusy = -1;
|
---|
703 | nvarmx ++;
|
---|
704 | if (nvarmx < 7) nvarmx = 7;
|
---|
705 | if (szv < 25) szv = 25;
|
---|
706 |
|
---|
707 | if ( (DVeci = (double**) malloc(nvarmx*sizeof(double *))) == NULL )
|
---|
708 | { printf("InitDFitLin_Erreur: (Pb malloc(Veci)) \n");
|
---|
709 | return(1);
|
---|
710 | }
|
---|
711 |
|
---|
712 | if ( (DVSpace = (double*) malloc(nvarmx*szv*sizeof(double))) == NULL )
|
---|
713 | { printf("InitDFitLin_Erreur: (Pb malloc(VSpace)) \n");
|
---|
714 | free(DVeci);
|
---|
715 | return(2);
|
---|
716 | }
|
---|
717 |
|
---|
718 | for(i=0; i<nvarmx; i++) *(DVeci+i) = DVSpace+i*szv;
|
---|
719 |
|
---|
720 |
|
---|
721 | if ( (DVecf = (double**) malloc(3*sizeof(double *))) == NULL )
|
---|
722 | { printf("InitDFitLin_Erreur: (Pb malloc(Vecf)) \n");
|
---|
723 | free(DVeci);
|
---|
724 | free(DVSpace);
|
---|
725 | return(3);
|
---|
726 | }
|
---|
727 |
|
---|
728 | if ( (DVSpacef = (double*) malloc(3*szv*sizeof(double))) == NULL )
|
---|
729 | { printf("InitDFitLin_Erreur: (Pb malloc(VSpacef)) \n");
|
---|
730 | free(DVeci);
|
---|
731 | free(DVSpace);
|
---|
732 | free(DVecf);
|
---|
733 | return(4);
|
---|
734 | }
|
---|
735 |
|
---|
736 | for(i=0; i<3; i++) *(DVecf+i) = DVSpacef+i*szv;
|
---|
737 |
|
---|
738 |
|
---|
739 | if ( (DFMtx = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
|
---|
740 | { printf("InitDFitLin_Erreur: (Pb malloc(FMtx)) \n");
|
---|
741 | free(DVeci);
|
---|
742 | free(DVSpace);
|
---|
743 | free(DVecf);
|
---|
744 | free(DVSpacef);
|
---|
745 | return(5);
|
---|
746 | }
|
---|
747 |
|
---|
748 | if ( (DFMtx2 = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
|
---|
749 | { printf("InitDFitLin_Erreur: (Pb malloc(FMtx2)) \n");
|
---|
750 | free(DVeci);
|
---|
751 | free(DVSpace);
|
---|
752 | free(DVecf);
|
---|
753 | free(DVSpacef);
|
---|
754 | free(DFMtx);
|
---|
755 | return(6);
|
---|
756 | }
|
---|
757 |
|
---|
758 | DFBusy = 0;
|
---|
759 | DNVarMax = nvarmx-1;
|
---|
760 | DVLenMax = szv;
|
---|
761 |
|
---|
762 | return(0);
|
---|
763 | }
|
---|
764 |
|
---|
765 |
|
---|
766 | /* Nouvelle-Fonction */
|
---|
767 | void EndDFitLin()
|
---|
768 | {
|
---|
769 |
|
---|
770 | if (DVeci != NULL) free(DVeci);
|
---|
771 | if (DVSpace != NULL) free(DVSpace);
|
---|
772 | if (DVecf != NULL) free(DVecf);
|
---|
773 | if (DVSpacef != NULL) free(DVSpacef);
|
---|
774 | if (DFMtx != NULL) free(DFMtx);
|
---|
775 | if (DFMtx2 != NULL) free(DFMtx2);
|
---|
776 |
|
---|
777 | DVeci = NULL;
|
---|
778 | DVSpace = NULL;
|
---|
779 | DVecf = NULL;
|
---|
780 | DVSpacef = NULL;
|
---|
781 | DFMtx = DFMtx2 = NULL;
|
---|
782 |
|
---|
783 | DFBusy = -1;
|
---|
784 | DNVarMax = 0;
|
---|
785 | DVLenMax = 0;
|
---|
786 | return;
|
---|
787 | }
|
---|
788 |
|
---|
789 |
|
---|
790 | /* Nouvelle-Fonction */
|
---|
791 |
|
---|
792 | double **GetDFitVect(int nvar, int vsz)
|
---|
793 | /* reservation de l'espace des vecteurs pour le fit */
|
---|
794 | {
|
---|
795 | int nvmx, vszmx;
|
---|
796 |
|
---|
797 | if (DFBusy > 0) return(NULL);
|
---|
798 | if ( (nvar < 1) || (vsz < 1) ) return(NULL);
|
---|
799 | if ((nvar > DNVarMax) || (vsz > DVLenMax) || (DFBusy < 0))
|
---|
800 | {
|
---|
801 | EndDFitLin();
|
---|
802 | if (nvar > DNVarMax) nvmx = nvar;
|
---|
803 | else nvmx = DNVarMax;
|
---|
804 | if (vsz > DVLenMax) vszmx = vsz;
|
---|
805 | else vszmx = DVLenMax;
|
---|
806 | InitDFitLin(nvmx, vszmx);
|
---|
807 | }
|
---|
808 |
|
---|
809 | DFBusy = 1;
|
---|
810 | return(DVeci);
|
---|
811 | }
|
---|
812 |
|
---|
813 |
|
---|
814 | /* Nouvelle-Fonction */
|
---|
815 | void FreeDFitVect()
|
---|
816 | {
|
---|
817 | DFBusy = 0;
|
---|
818 | return;
|
---|
819 | }
|
---|
820 |
|
---|
821 |
|
---|
822 | /* Nouvelle-Fonction */
|
---|
823 |
|
---|
824 | double DFitLin(int nd, int vsz, double *XVar)
|
---|
825 |
|
---|
826 | /* Effectue le fit de Xi2 pour nd inconnu, Taille vecteurs vsz */
|
---|
827 | /* Les vecteurs doivent etre remplis auparavant */
|
---|
828 | /* Retourne la valeur du Xi2 du fit, Negatif si Pb. */
|
---|
829 |
|
---|
830 | {
|
---|
831 | int i,j;
|
---|
832 | register double *ip;
|
---|
833 | register double *fp, *fp2;
|
---|
834 | register double x,y;
|
---|
835 | double det,rc;
|
---|
836 |
|
---|
837 |
|
---|
838 | if ((nd > DNVarMax) || (vsz > DVLenMax) ) { rc = -1000.; goto Fin; }
|
---|
839 |
|
---|
840 | /* Impression de debug */
|
---|
841 | /*
|
---|
842 | for(i=0; i<nd+1; i++)
|
---|
843 | {
|
---|
844 | ip = *(DVeci+i);
|
---|
845 | printf("DFitLin_Debug Veci[%d][0..5]= %lg %lg %lg %lg %lg %lg \n",
|
---|
846 | i,*ip, *(ip+1), *(ip+2), *(ip+3), *(ip+4), *(ip+5));
|
---|
847 | }
|
---|
848 | */
|
---|
849 |
|
---|
850 |
|
---|
851 | /* Fabrication matrice du syteme lineaire a resoudre */
|
---|
852 |
|
---|
853 | for(i=0; i<nd; i++)
|
---|
854 | {
|
---|
855 | fp = DFMtx+i*nd; fp2 = DFMtx2+i*nd;
|
---|
856 | ip = *(DVeci+i+1);
|
---|
857 |
|
---|
858 | /* Elements diagonals */
|
---|
859 | *(fp2+i) = *(fp+i) = DVecxVec( ip, ip, vsz) ;
|
---|
860 |
|
---|
861 | for(j=i+1; j<nd; j++)
|
---|
862 | { /* Les autres elements */
|
---|
863 | *(fp2+j) = *(fp+j) = DVecxVec( ip, *(DVeci+j+1), vsz) ;
|
---|
864 | /* Matrice symetrique */
|
---|
865 | *(DFMtx2+j*nd+i) = *(DFMtx+j*nd+i) = *(fp+j);
|
---|
866 | }
|
---|
867 |
|
---|
868 | /* Second membre M.X = B */
|
---|
869 | fp = *DVecf; fp2 = *(DVecf+2);
|
---|
870 | *(fp2+i) = *(fp+i) = DVecxVec( ip, *DVeci, vsz) ;
|
---|
871 |
|
---|
872 | }
|
---|
873 |
|
---|
874 | /*
|
---|
875 | printf("DFitLin_Debug B[0..5]= %lg %lg %lg %lg %lg %lg \n",
|
---|
876 | *fp2, *(fp2+1), *(fp2+2), *(fp2+3), *(fp2+4), *(fp2+5));
|
---|
877 | */
|
---|
878 |
|
---|
879 | /* On resoud le systeme lineaire : */
|
---|
880 | fp = *(DVecf+1);
|
---|
881 | det = SolveDLinSyst(DFMtx, *DVecf, fp, nd);
|
---|
882 | if (det == 0.0) { rc = -500.; goto Fin; }
|
---|
883 |
|
---|
884 | /* On calcule le Xi2 */
|
---|
885 | x = DVecxVec( *DVeci, *DVeci, vsz);
|
---|
886 | for(i=0; i<nd; i++) /* Et on remplit le vecteur de sortie */
|
---|
887 | {
|
---|
888 | fp2 = DFMtx2+i*nd+i; y = XVar[i] = *(*(DVecf+1)+i);
|
---|
889 | x += (y * y * *fp2);
|
---|
890 | x -= ( 2.0 * ( y * *(*(DVecf+2)+i) ) );
|
---|
891 | for (j=i+1; j<nd; j++)
|
---|
892 | { fp2++;
|
---|
893 | x += ( 2.0 * ( y * *(*(DVecf+1)+j) * *fp2 ) ); }
|
---|
894 | }
|
---|
895 | rc = x;
|
---|
896 |
|
---|
897 |
|
---|
898 | Fin:
|
---|
899 | FreeDFitVect();
|
---|
900 | return(rc);
|
---|
901 | }
|
---|
902 |
|
---|
903 |
|
---|
904 |
|
---|