00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <math.h>
00026 #include <float.h>
00027
00028 #include "sba.h"
00029
00030
00031 #define FABS(x) (((x)>=0)? (x) : -(x))
00032
00033 struct wrap_motstr_data_ {
00034 void (*proj)(int j, int i, double *aj, double *bi, double *xij, void *adata);
00035 void (*projac)(int j, int i, double *aj, double *bi, double *Aij, double *Bij, void *adata);
00036 int cnp, pnp, mnp;
00037 void *adata;
00038 };
00039
00040 struct wrap_mot_data_ {
00041 void (*proj)(int j, int i, double *aj, double *xij, void *adata);
00042 void (*projac)(int j, int i, double *aj, double *Aij, void *adata);
00043 int cnp, mnp;
00044 void *adata;
00045 };
00046
00047 struct wrap_str_data_ {
00048 void (*proj)(int j, int i, double *bi, double *xij, void *adata);
00049 void (*projac)(int j, int i, double *bi, double *Bij, void *adata);
00050 int pnp, mnp;
00051 void *adata;
00052 };
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static void sba_motstr_Qs(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *hx, void *adata)
00074 {
00075 register int i, j;
00076 int cnp, pnp, mnp;
00077 double *pa, *pb, *paj, *pbi, *pxij;
00078 int n, m, nnz;
00079 struct wrap_motstr_data_ *wdata;
00080 void (*proj)(int j, int i, double *aj, double *bi, double *xij, void *proj_adata);
00081 void *proj_adata;
00082
00083 wdata=(struct wrap_motstr_data_ *)adata;
00084 cnp=wdata->cnp; pnp=wdata->pnp; mnp=wdata->mnp;
00085 proj=wdata->proj;
00086 proj_adata=wdata->adata;
00087
00088 n=idxij->nr; m=idxij->nc;
00089 pa=p; pb=p+m*cnp;
00090
00091 for(j=0; j<m; ++j){
00092
00093 paj=pa+j*cnp;
00094
00095 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00096
00097 for(i=0; i<nnz; ++i){
00098 pbi=pb + rcsubs[i]*pnp;
00099 pxij=hx + idxij->val[rcidxs[i]]*mnp;
00100
00101 (*proj)(j, rcsubs[i], paj, pbi, pxij, proj_adata);
00102 }
00103 }
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 static void sba_motstr_Qs_jac(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata)
00115 {
00116 register int i, j;
00117 int cnp, pnp, mnp;
00118 double *pa, *pb, *paj, *pbi, *pAij, *pBij;
00119 int n, m, nnz, Asz, Bsz, ABsz, idx;
00120 struct wrap_motstr_data_ *wdata;
00121 void (*projac)(int j, int i, double *aj, double *bi, double *Aij, double *Bij, void *projac_adata);
00122 void *projac_adata;
00123
00124
00125 wdata=(struct wrap_motstr_data_ *)adata;
00126 cnp=wdata->cnp; pnp=wdata->pnp; mnp=wdata->mnp;
00127 projac=wdata->projac;
00128 projac_adata=wdata->adata;
00129
00130 n=idxij->nr; m=idxij->nc;
00131 pa=p; pb=p+m*cnp;
00132 Asz=mnp*cnp; Bsz=mnp*pnp; ABsz=Asz+Bsz;
00133
00134 for(j=0; j<m; ++j){
00135
00136 paj=pa+j*cnp;
00137
00138 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00139
00140 for(i=0; i<nnz; ++i){
00141 pbi=pb + rcsubs[i]*pnp;
00142 idx=idxij->val[rcidxs[i]];
00143 pAij=jac + idx*ABsz;
00144 pBij=pAij + Asz;
00145
00146 (*projac)(j, rcsubs[i], paj, pbi, pAij, pBij, projac_adata);
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 static void sba_motstr_Qs_fdjac(
00164 double *p,
00165 struct sba_crsm *idxij,
00166 int *rcidxs,
00167 int *rcsubs,
00168 double *jac,
00169 void *dat)
00170 {
00171 register int i, j, ii, jj;
00172 double *pa, *pb, *paj, *pbi;
00173 register double *pAB;
00174 int n, m, nnz, Asz, Bsz, ABsz;
00175
00176 double tmp;
00177 register double d, d1;
00178
00179 struct wrap_motstr_data_ *fdjd;
00180 void (*proj)(int j, int i, double *aj, double *bi, double *xij, void *adata);
00181 double *hxij, *hxxij;
00182 int cnp, pnp, mnp;
00183 void *adata;
00184
00185
00186 fdjd=(struct wrap_motstr_data_ *)dat;
00187 proj=fdjd->proj;
00188 cnp=fdjd->cnp; pnp=fdjd->pnp; mnp=fdjd->mnp;
00189 adata=fdjd->adata;
00190
00191 n=idxij->nr; m=idxij->nc;
00192 pa=p; pb=p+m*cnp;
00193 Asz=mnp*cnp; Bsz=mnp*pnp; ABsz=Asz+Bsz;
00194
00195
00196 if((hxij=malloc(2*mnp*sizeof(double)))==NULL){
00197 fprintf(stderr, "memory allocation request failed in sba_motstr_Qs_fdjac()!\n");
00198 exit(1);
00199 }
00200 hxxij=hxij+mnp;
00201
00202
00203 for(j=0; j<m; ++j){
00204 paj=pa+j*cnp;
00205
00206 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00207 for(jj=0; jj<cnp; ++jj){
00208
00209 d=(double)(SBA_DELTA_SCALE)*paj[jj];
00210 d=FABS(d);
00211 if(d<SBA_MIN_DELTA) d=SBA_MIN_DELTA;
00212 d1=1.0/d;
00213
00214 for(i=0; i<nnz; ++i){
00215 pbi=pb + rcsubs[i]*pnp;
00216 (*proj)(j, rcsubs[i], paj, pbi, hxij, adata);
00217
00218 tmp=paj[jj];
00219 paj[jj]+=d;
00220 (*proj)(j, rcsubs[i], paj, pbi, hxxij, adata);
00221 paj[jj]=tmp;
00222
00223 pAB=jac + idxij->val[rcidxs[i]]*ABsz;
00224 for(ii=0; ii<mnp; ++ii)
00225 pAB[ii*cnp+jj]=(hxxij[ii]-hxij[ii])*d1;
00226 }
00227 }
00228 }
00229
00230
00231 for(i=0; i<n; ++i){
00232 pbi=pb+i*pnp;
00233
00234 nnz=sba_crsm_row_elmidxs(idxij, i, rcidxs, rcsubs);
00235 for(jj=0; jj<pnp; ++jj){
00236
00237 d=(double)(SBA_DELTA_SCALE)*pbi[jj];
00238 d=FABS(d);
00239 if(d<SBA_MIN_DELTA) d=SBA_MIN_DELTA;
00240 d1=1.0/d;
00241
00242 for(j=0; j<nnz; ++j){
00243 paj=pa + rcsubs[j]*cnp;
00244 (*proj)(rcsubs[j], i, paj, pbi, hxij, adata);
00245
00246 tmp=pbi[jj];
00247 pbi[jj]+=d;
00248 (*proj)(rcsubs[j], i, paj, pbi, hxxij, adata);
00249 pbi[jj]=tmp;
00250
00251 pAB=jac + idxij->val[rcidxs[j]]*ABsz + Asz;
00252 for(ii=0; ii<mnp; ++ii)
00253 pAB[ii*pnp+jj]=(hxxij[ii]-hxij[ii])*d1;
00254 }
00255 }
00256 }
00257
00258 free(hxij);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 static void sba_mot_Qs(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *hx, void *adata)
00272 {
00273 register int i, j;
00274 int cnp, mnp;
00275 double *paj, *pxij;
00276
00277 int m, nnz;
00278 struct wrap_mot_data_ *wdata;
00279 void (*proj)(int j, int i, double *aj, double *xij, void *proj_adata);
00280 void *proj_adata;
00281
00282 wdata=(struct wrap_mot_data_ *)adata;
00283 cnp=wdata->cnp; mnp=wdata->mnp;
00284 proj=wdata->proj;
00285 proj_adata=wdata->adata;
00286
00287
00288 m=idxij->nc;
00289
00290 for(j=0; j<m; ++j){
00291
00292 paj=p+j*cnp;
00293
00294 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00295
00296 for(i=0; i<nnz; ++i){
00297 pxij=hx + idxij->val[rcidxs[i]]*mnp;
00298
00299 (*proj)(j, rcsubs[i], paj, pxij, proj_adata);
00300 }
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 static void sba_mot_Qs_jac(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata)
00313 {
00314 register int i, j;
00315 int cnp, mnp;
00316 double *paj, *pAij;
00317
00318 int m, nnz, Asz, idx;
00319 struct wrap_mot_data_ *wdata;
00320 void (*projac)(int j, int i, double *aj, double *Aij, void *projac_adata);
00321 void *projac_adata;
00322
00323 wdata=(struct wrap_mot_data_ *)adata;
00324 cnp=wdata->cnp; mnp=wdata->mnp;
00325 projac=wdata->projac;
00326 projac_adata=wdata->adata;
00327
00328
00329 m=idxij->nc;
00330 Asz=mnp*cnp;
00331
00332 for(j=0; j<m; ++j){
00333
00334 paj=p+j*cnp;
00335
00336 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00337
00338 for(i=0; i<nnz; ++i){
00339 idx=idxij->val[rcidxs[i]];
00340 pAij=jac + idx*Asz;
00341
00342 (*projac)(j, rcsubs[i], paj, pAij, projac_adata);
00343 }
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 static void sba_mot_Qs_fdjac(
00359 double *p,
00360 struct sba_crsm *idxij,
00361 int *rcidxs,
00362 int *rcsubs,
00363 double *jac,
00364 void *dat)
00365 {
00366 register int i, j, ii, jj;
00367 double *paj;
00368 register double *pA;
00369
00370 int m, nnz, Asz;
00371
00372 double tmp;
00373 register double d, d1;
00374
00375 struct wrap_mot_data_ *fdjd;
00376 void (*proj)(int j, int i, double *aj, double *xij, void *adata);
00377 double *hxij, *hxxij;
00378 int cnp, mnp;
00379 void *adata;
00380
00381
00382 fdjd=(struct wrap_mot_data_ *)dat;
00383 proj=fdjd->proj;
00384 cnp=fdjd->cnp; mnp=fdjd->mnp;
00385 adata=fdjd->adata;
00386
00387
00388 m=idxij->nc;
00389 Asz=mnp*cnp;
00390
00391
00392 if((hxij=malloc(2*mnp*sizeof(double)))==NULL){
00393 fprintf(stderr, "memory allocation request failed in sba_mot_Qs_fdjac()!\n");
00394 exit(1);
00395 }
00396 hxxij=hxij+mnp;
00397
00398
00399 for(j=0; j<m; ++j){
00400 paj=p+j*cnp;
00401
00402 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00403 for(jj=0; jj<cnp; ++jj){
00404
00405 d=(double)(SBA_DELTA_SCALE)*paj[jj];
00406 d=FABS(d);
00407 if(d<SBA_MIN_DELTA) d=SBA_MIN_DELTA;
00408 d1=1.0/d;
00409
00410 for(i=0; i<nnz; ++i){
00411 (*proj)(j, rcsubs[i], paj, hxij, adata);
00412
00413 tmp=paj[jj];
00414 paj[jj]+=d;
00415 (*proj)(j, rcsubs[i], paj, hxxij, adata);
00416 paj[jj]=tmp;
00417
00418 pA=jac + idxij->val[rcidxs[i]]*Asz;
00419 for(ii=0; ii<mnp; ++ii)
00420 pA[ii*cnp+jj]=(hxxij[ii]-hxij[ii])*d1;
00421 }
00422 }
00423 }
00424
00425 free(hxij);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 static void sba_str_Qs(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *hx, void *adata)
00439 {
00440 register int i, j;
00441 int pnp, mnp;
00442 double *pbi, *pxij;
00443
00444 int m, nnz;
00445 struct wrap_str_data_ *wdata;
00446 void (*proj)(int j, int i, double *bi, double *xij, void *proj_adata);
00447 void *proj_adata;
00448
00449 wdata=(struct wrap_str_data_ *)adata;
00450 pnp=wdata->pnp; mnp=wdata->mnp;
00451 proj=wdata->proj;
00452 proj_adata=wdata->adata;
00453
00454
00455 m=idxij->nc;
00456
00457 for(j=0; j<m; ++j){
00458 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00459
00460 for(i=0; i<nnz; ++i){
00461 pbi=p + rcsubs[i]*pnp;
00462 pxij=hx + idxij->val[rcidxs[i]]*mnp;
00463
00464 (*proj)(j, rcsubs[i], pbi, pxij, proj_adata);
00465 }
00466 }
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476 static void sba_str_Qs_jac(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata)
00477 {
00478 register int i, j;
00479 int pnp, mnp;
00480 double *pbi, *pBij;
00481
00482 int m, nnz, Bsz, idx;
00483 struct wrap_str_data_ *wdata;
00484 void (*projac)(int j, int i, double *bi, double *Bij, void *projac_adata);
00485 void *projac_adata;
00486
00487
00488 wdata=(struct wrap_str_data_ *)adata;
00489 pnp=wdata->pnp; mnp=wdata->mnp;
00490 projac=wdata->projac;
00491 projac_adata=wdata->adata;
00492
00493
00494 m=idxij->nc;
00495 Bsz=mnp*pnp;
00496
00497 for(j=0; j<m; ++j){
00498
00499 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs);
00500
00501 for(i=0; i<nnz; ++i){
00502 pbi=p + rcsubs[i]*pnp;
00503 idx=idxij->val[rcidxs[i]];
00504 pBij=jac + idx*Bsz;
00505
00506 (*projac)(j, rcsubs[i], pbi, pBij, projac_adata);
00507 }
00508 }
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 static void sba_str_Qs_fdjac(
00523 double *p,
00524 struct sba_crsm *idxij,
00525 int *rcidxs,
00526 int *rcsubs,
00527 double *jac,
00528 void *dat)
00529 {
00530 register int i, j, ii, jj;
00531 double *pbi;
00532 register double *pB;
00533
00534 int n, nnz, Bsz;
00535
00536 double tmp;
00537 register double d, d1;
00538
00539 struct wrap_str_data_ *fdjd;
00540 void (*proj)(int j, int i, double *bi, double *xij, void *adata);
00541 double *hxij, *hxxij;
00542 int pnp, mnp;
00543 void *adata;
00544
00545
00546 fdjd=(struct wrap_str_data_ *)dat;
00547 proj=fdjd->proj;
00548 pnp=fdjd->pnp; mnp=fdjd->mnp;
00549 adata=fdjd->adata;
00550
00551 n=idxij->nr;
00552
00553 Bsz=mnp*pnp;
00554
00555
00556 if((hxij=malloc(2*mnp*sizeof(double)))==NULL){
00557 fprintf(stderr, "memory allocation request failed in sba_str_Qs_fdjac()!\n");
00558 exit(1);
00559 }
00560 hxxij=hxij+mnp;
00561
00562
00563 for(i=0; i<n; ++i){
00564 pbi=p+i*pnp;
00565
00566 nnz=sba_crsm_row_elmidxs(idxij, i, rcidxs, rcsubs);
00567 for(jj=0; jj<pnp; ++jj){
00568
00569 d=(double)(SBA_DELTA_SCALE)*pbi[jj];
00570 d=FABS(d);
00571 if(d<SBA_MIN_DELTA) d=SBA_MIN_DELTA;
00572 d1=1.0/d;
00573
00574 for(j=0; j<nnz; ++j){
00575 (*proj)(rcsubs[j], i, pbi, hxij, adata);
00576
00577 tmp=pbi[jj];
00578 pbi[jj]+=d;
00579 (*proj)(rcsubs[j], i, pbi, hxxij, adata);
00580 pbi[jj]=tmp;
00581
00582 pB=jac + idxij->val[rcidxs[j]]*Bsz;
00583 for(ii=0; ii<mnp; ++ii)
00584 pB[ii*pnp+jj]=(hxxij[ii]-hxij[ii])*d1;
00585 }
00586 }
00587 }
00588
00589 free(hxij);
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599 int sba_motstr_levmar(
00600 const int n,
00601 const int ncon,
00602
00603
00604 const int m,
00605 const int mcon,
00606
00607
00608 char *vmask,
00609 double *p,
00610
00611
00612
00613 const int cnp,
00614 const int pnp,
00615 double *x,
00616
00617
00618
00619
00620 double *covx,
00621
00622
00623
00624
00625
00626 const int mnp,
00627 void (*proj)(int j, int i, double *aj, double *bi, double *xij, void *adata),
00628
00629
00630
00631
00632
00633
00634 void (*projac)(int j, int i, double *aj, double *bi, double *Aij, double *Bij, void *adata),
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 void *adata,
00645
00646 const int itmax,
00647 const int verbose,
00648 const double opts[SBA_OPTSSZ],
00649
00650
00651
00652 double info[SBA_INFOSZ]
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 )
00669 {
00670 int retval;
00671 struct wrap_motstr_data_ wdata;
00672 static void (*fjac)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata);
00673
00674 wdata.proj=proj;
00675 wdata.projac=projac;
00676 wdata.cnp=cnp;
00677 wdata.pnp=pnp;
00678 wdata.mnp=mnp;
00679 wdata.adata=adata;
00680
00681 fjac=(projac)? sba_motstr_Qs_jac : sba_motstr_Qs_fdjac;
00682 retval=sba_motstr_levmar_x(n, ncon, m, mcon, vmask, p, cnp, pnp, x, covx, mnp, sba_motstr_Qs, fjac, &wdata, itmax, verbose, opts, info);
00683
00684 if(info){
00685 register int i;
00686 int nvis;
00687
00688
00689 for(i=nvis=0; i<n*m; ++i)
00690 nvis+=(vmask[i]!=0);
00691
00692
00693 info[7]*=nvis;
00694 info[8]*=nvis;
00695 }
00696
00697 return retval;
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707 int sba_mot_levmar(
00708 const int n,
00709 const int m,
00710 const int mcon,
00711
00712
00713 char *vmask,
00714 double *p,
00715
00716 const int cnp,
00717 double *x,
00718
00719
00720
00721
00722 double *covx,
00723
00724
00725
00726
00727
00728 const int mnp,
00729 void (*proj)(int j, int i, double *aj, double *xij, void *adata),
00730
00731
00732
00733
00734
00735 void (*projac)(int j, int i, double *aj, double *Aij, void *adata),
00736
00737
00738
00739
00740
00741
00742
00743
00744 void *adata,
00745
00746 const int itmax,
00747 const int verbose,
00748 const double opts[SBA_OPTSSZ],
00749
00750
00751
00752 double info[SBA_INFOSZ]
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 )
00769 {
00770 int retval;
00771 struct wrap_mot_data_ wdata;
00772 void (*fjac)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata);
00773
00774 wdata.proj=proj;
00775 wdata.projac=projac;
00776 wdata.cnp=cnp;
00777 wdata.mnp=mnp;
00778 wdata.adata=adata;
00779
00780 fjac=(projac)? sba_mot_Qs_jac : sba_mot_Qs_fdjac;
00781 retval=sba_mot_levmar_x(n, m, mcon, vmask, p, cnp, x, covx, mnp, sba_mot_Qs, fjac, &wdata, itmax, verbose, opts, info);
00782
00783 if(info){
00784 register int i;
00785 int nvis;
00786
00787
00788 for(i=nvis=0; i<n*m; ++i)
00789 nvis+=(vmask[i]!=0);
00790
00791
00792 info[7]*=nvis;
00793 info[8]*=nvis;
00794 }
00795
00796 return retval;
00797 }
00798
00799
00800
00801
00802
00803
00804
00805 int sba_str_levmar(
00806 const int n,
00807 const int ncon,
00808
00809
00810 const int m,
00811 char *vmask,
00812 double *p,
00813
00814
00815 const int pnp,
00816 double *x,
00817
00818
00819
00820
00821 double *covx,
00822
00823
00824
00825
00826
00827 const int mnp,
00828 void (*proj)(int j, int i, double *bi, double *xij, void *adata),
00829
00830
00831
00832
00833
00834 void (*projac)(int j, int i, double *bi, double *Bij, void *adata),
00835
00836
00837
00838
00839
00840
00841
00842
00843 void *adata,
00844
00845 const int itmax,
00846 const int verbose,
00847 const double opts[SBA_OPTSSZ],
00848
00849
00850
00851 double info[SBA_INFOSZ]
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 )
00868 {
00869 int retval;
00870 struct wrap_str_data_ wdata;
00871 static void (*fjac)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata);
00872
00873 wdata.proj=proj;
00874 wdata.projac=projac;
00875 wdata.pnp=pnp;
00876 wdata.mnp=mnp;
00877 wdata.adata=adata;
00878
00879 fjac=(projac)? sba_str_Qs_jac : sba_str_Qs_fdjac;
00880 retval=sba_str_levmar_x(n, ncon, m, vmask, p, pnp, x, covx, mnp, sba_str_Qs, fjac, &wdata, itmax, verbose, opts, info);
00881
00882 if(info){
00883 register int i;
00884 int nvis;
00885
00886
00887 for(i=nvis=0; i<n*m; ++i)
00888 nvis+=(vmask[i]!=0);
00889
00890
00891 info[7]*=nvis;
00892 info[8]*=nvis;
00893 }
00894
00895 return retval;
00896 }