10 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
18 #include "../Options/Options.h"
21 #include "../../datastructures/datastructures.h"
22 #include "../../shared/shared.h"
27 #include "../../toolkits/toolkits.h"
35 this->quadtree = NULL;
36 this->covertree = NULL;
43 if(n<=0)
_error_(
"No observation found");
47 options->
Get(&dtree,
"treetype",1.);
48 this->treetype = reCast<int>(dtree);
49 switch(this->treetype){
51 this->covertree = NULL;
52 this->InitQuadtree(observations_list,x,y,n,options);
55 this->quadtree = NULL;
56 this->InitCovertree(observations_list,x,y,n,options);
59 _error_(
"Tree type "<<this->treetype<<
" not supported yet (1: quadtree, 2: covertree)");
64 switch(this->treetype){
66 delete this->quadtree;
69 delete this->covertree;
72 _printf_(
"Tree type "<<this->treetype<<
" not supported yet (1: quadtree, 2: covertree)");
88 options->
Get(&mintrimming,
"mintrimming",-1.e+21);
89 options->
Get(&maxtrimming,
"maxtrimming",+1.e+21);
90 options->
Get(&minspacing,
"minspacing",0.01);
91 if(minspacing<=0)
_error_(
"minspacing must > 0");
102 for(
int i=1;i<n;i++){
103 if(x[i]<xmin) xmin=x[i];
104 if(x[i]>xmax) xmax=x[i];
105 if(y[i]<ymin) ymin=y[i];
106 if(y[i]>ymax) ymax=y[i];
108 IssmPDouble maxDist = sqrt(pow(xmax-xmin,2)+pow(ymax-ymin,2));
110 int maxdepth = ceilf(log(maxDist)/log(base));
112 _printf0_(
"Generating covertree with a maximum depth " << maxdepth <<
"... ");
115 for(
int i=0;i<n;i++){
118 if(observations_list[i]>maxtrimming)
continue;
119 if(observations_list[i]<mintrimming)
continue;
123 if(i>0 && this->covertree->getRoot()){
125 std::vector<Observation> kNN=(this->covertree->kNearestNeighbors(newobs,1));
127 if(oldobs.
distance(newobs)<minspacing)
continue;
130 this->covertree->insert(newobs);
138 int i,maxdepth,level,counter,index;
141 IssmPDouble offset,minlength,minspacing,mintrimming,maxtrimming;
148 xmin=x[0]; ymin=y[0];
149 xmax=x[0]; ymax=y[0];
151 xmin=
min(xmin,x[i]); ymin=
min(ymin,y[i]);
152 xmax=
max(xmax,x[i]); ymax=
max(ymax,y[i]);
154 offset=0.05*(xmax-xmin); xmin-=offset; xmax+=offset;
155 offset=0.05*(ymax-ymin); ymin-=offset; ymax+=offset;
158 options->
Get(&mintrimming,
"mintrimming",-1.e+21);
159 options->
Get(&maxtrimming,
"maxtrimming",+1.e+21);
160 options->
Get(&minspacing,
"minspacing",0.01);
161 if(minspacing<=0)
_error_(
"minspacing must > 0");
165 options->
Get(&minlength,
"boxlength");
166 if(minlength<=0)
_error_(
"boxlength should be a positive number");
167 maxdepth=reCast<int,IssmPDouble>(log(
max(xmax-xmin,ymax-ymin)/minlength +1)/log(2.0));
175 _printf0_(
"Generating quadtree with a maximum box size " << minlength <<
" (depth=" << maxdepth <<
")... ");
176 this->quadtree =
new Quadtree(xmin,xmax,ymin,ymax,maxdepth);
183 if(observations_list[i]>maxtrimming)
continue;
184 if(observations_list[i]<mintrimming)
continue;
187 this->quadtree->ClosestObs(&index,x[i],y[i]);
189 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(index));
190 if(pow(observation->
x-x[i],2)+pow(observation->
y-y[i],2) < minspacing)
continue;
193 this->quadtree->IntergerCoordinates(&xi,&yi,x[i],y[i]);
194 this->quadtree->QuadtreeDepth2(&level,xi,yi);
195 if((
int)level <= maxdepth){
196 observation =
new Observation(x[i],y[i],xi,yi,counter++,observations_list[i]);
197 this->quadtree->Add(observation);
198 this->AddObject(observation);
202 this->quadtree->AddAndAverage(x[i],y[i],observations_list[i]);
206 _printf0_(
"Initial number of observations: " << n <<
"\n");
207 _printf0_(
" Final number of observations: " << this->quadtree->NbObs <<
"\n");
214 switch(this->treetype){
216 this->ClosestObservationQuadtree(px,py,pobs,x_interp,y_interp,radius);
219 this->ClosestObservationCovertree(px,py,pobs,x_interp,y_interp,radius);
222 _error_(
"Tree type "<<this->treetype<<
" not supported yet (1: quadtree, 2: covertree)");
230 if(this->covertree->getRoot()){
233 std::vector<Observation> kNN=(this->covertree->kNearestNeighbors(newobs,1));
235 hmin = observation.
distance(newobs);
239 *pobs = observation.
value;
257 if(radius==0) radius=this->quadtree->root->length;
263 this->quadtree->ClosestObs(&index,x_interp,y_interp);
265 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(index));
266 hmin = sqrt((observation->
x-x_interp)*(observation->
x-x_interp) + (observation->
y-y_interp)*(observation->
y-y_interp));
267 if(hmin<radius) radius=hmin;
271 this->quadtree->RangeSearch(&indices,&nobs,x_interp,y_interp,radius);
272 for (i=0;i<nobs;i++){
273 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(indices[i]));
274 h2 = (observation->
x-x_interp)*(observation->
x-x_interp) + (observation->
y-y_interp)*(observation->
y-y_interp);
288 if(nobs || hmin==radius){
289 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(index));
290 *px = observation->
x;
291 *py = observation->
y;
292 *pobs = observation->
value;
299 xDelete<int>(indices);
306 for(
int i=0;i<n;i++){
307 this->ClosestObservation(&xi,&yi,&obs,x[i],y[i],radius);
312 distances[i]=sqrt( (x[i]-xi)*(x[i]-xi) + (y[i]-yi)*(y[i]-yi) );
328 x = xNew<IssmPDouble>(nobs);
329 y = xNew<IssmPDouble>(nobs);
330 obs = xNew<IssmPDouble>(nobs);
331 for(
int i=0;i<this->Size();i++){
332 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(i));
345 switch(this->treetype){
347 this->ObservationListQuadtree(px,py,pobs,pnobs,x_interp,y_interp,radius,maxdata);
350 this->ObservationListCovertree(px,py,pobs,pnobs,x_interp,y_interp,radius,maxdata);
353 _error_(
"Tree type "<<this->treetype<<
" not supported yet (1: quadtree, 2: covertree)");
362 std::vector<Observation> kNN;
364 kNN=(this->covertree->kNearestNeighbors(observation, maxdata));
370 vector<Observation>::iterator it;
372 for (it = kNN.begin(); it != kNN.end(); ++it) {
375 if ((*it).distance(observation) > radius) {
379 kNN.erase(it, kNN.end());
383 x =
new double[kNN.size()];
384 y =
new double[kNN.size()];
385 obs =
new double[kNN.size()];
389 for(it = kNN.begin(); it != kNN.end(); ++it) {
390 (*it).WriteXYObs((*it), &x[i], &y[i], &obs[i]);
403 int nobs,tempnobs,i,j,k,n,counter;
406 int *tempindices = NULL;
414 if(radius==0.) radius=this->quadtree->root->length*2.;
417 radius2 = radius*radius;
420 this->quadtree->RangeSearch(&tempindices,&tempnobs,x_interp,y_interp,radius);
422 indices = xNew<int>(tempnobs);
423 dists = xNew<IssmPDouble>(tempnobs);
426 for(i=0;i<tempnobs;i++){
427 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(tempindices[i]));
428 h2 = (observation->
x-x_interp)*(observation->
x-x_interp) + (observation->
y-y_interp)*(observation->
y-y_interp);
430 if(nobs==maxdata && h2>radius2)
continue;
432 indices[nobs] = tempindices[i];
436 if(nobs==1)
continue;
444 for(
int jj=k;jj<n;jj++){
446 dists[j+1] = dists[j];
447 indices[j+1] = indices[j];
451 indices[k] = tempindices[i];
458 xDelete<IssmPDouble>(dists);
459 xDelete<int>(tempindices);
463 x = xNew<IssmPDouble>(nobs);
464 y = xNew<IssmPDouble>(nobs);
465 obs = xNew<IssmPDouble>(nobs);
469 observation=xDynamicCast<Observation*>(this->GetObjectByOffset(indices[i]));
475 xDelete<int>(indices);
497 this->ObservationList(&x,&y,&obs,&n_obs,x_interp,y_interp,radius,maxdata);
506 for(i=0;i<n_obs;i++){
507 h = sqrt( (x[i]-x_interp)*(x[i]-x_interp) + (y[i]-y_interp)*(y[i]-y_interp));
513 weight = 1./pow(h,power);
514 numerator += weight*obs[i];
515 denominator += weight;
517 prediction = numerator/denominator;
521 *pprediction = prediction;
522 xDelete<IssmPDouble>(x);
523 xDelete<IssmPDouble>(y);
524 xDelete<IssmPDouble>(obs);
541 this->ObservationList(&x,&y,&obs,&n_obs,x_interp,y_interp,radius,maxdata);
545 *pprediction = -999.0;
551 IssmPDouble* A = xNew<IssmPDouble>((n_obs+1)*(n_obs+1));
556 for(i=0;i<n_obs;i++){
559 A[i*(n_obs+1)+j] = variogram->
Covariance(x[i]-x[j],y[i]-y[j]);
560 A[j*(n_obs+1)+i] = A[i*(n_obs+1)+j];
562 A[i*(n_obs+1)+n_obs] = unbias;
565 for(i=0;i<n_obs;i++) A[n_obs*(n_obs+1)+i]=unbias;
567 A[n_obs*(n_obs+1)+n_obs] = 0.;
570 for(i=0;i<n_obs;i++) B[i] = variogram->
Covariance(x[i]-x_interp,y[i]-y_interp);
583 for(i=0;i<n_obs;i++) prediction += Lambda[i]*obs[i];
586 error = variogram->
Covariance(0.,0.)*(1. - Lambda[n_obs]);;
587 for(i=0;i<n_obs;i++) error += -Lambda[i]*B[i];
590 *pprediction = prediction;
592 xDelete<IssmPDouble>(x);
593 xDelete<IssmPDouble>(y);
594 xDelete<IssmPDouble>(obs);
595 xDelete<IssmPDouble>(A);
596 xDelete<IssmPDouble>(B);
597 xDelete<IssmPDouble>(Lambda);
605 this->ClosestObservation(&x,&y,&obs,x_interp,y_interp,radius);
631 this->ObservationList(&x,&y,&obs,&n_obs,x_interp,y_interp,radius,maxdata);
634 if(n_obs<mindata || n_obs<2){
640 Green = xNew<IssmPDouble>(n_obs*n_obs);
641 g = xNew<IssmPDouble>(n_obs);
644 for(i=0;i<n_obs;i++){
645 h = sqrt( (x[i]-x_interp)*(x[i]-x_interp) + (y[i]-y_interp)*(y[i]-y_interp) );
647 g[i] = h*h*(log(h)-1.);
655 for(i=0;i<n_obs;i++){
657 h = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) );
659 Green[j*n_obs+i] = h*h*(log(h)-1.);
662 Green[j*n_obs+i] = 0.;
664 Green[i*n_obs+j] = Green[j*n_obs+i];
667 Green[i*n_obs+i] = 0.;
679 for(i=0;i<n_obs;i++) prediction += weights[i]*g[i];
684 *pprediction = prediction;
685 xDelete<IssmPDouble>(x);
686 xDelete<IssmPDouble>(y);
687 xDelete<IssmPDouble>(obs);
688 xDelete<IssmPDouble>(Green);
689 xDelete<IssmPDouble>(g);
690 xDelete<IssmPDouble>(weights);
694 if(this->treetype!=1)
_error_(
"Tree type is not quadtree");
697 for(
int i=0;i<n;i++){
698 this->quadtree->IntergerCoordinates(&xi,&yi,x[i],y[i]);
699 this->quadtree->QuadtreeDepth(&level,xi,yi);
713 for(j=0;j<n;j++) counter[j] = 0.0;
714 for(j=0;j<n;j++) gamma[j] = 0.0;
716 for(i=0;i<this->Size();i++){
717 observation1=xDynamicCast<Observation*>(this->GetObjectByOffset(i));
719 for(j=i+1;j<this->Size();j++){
720 observation2=xDynamicCast<Observation*>(this->GetObjectByOffset(j));
722 distance=sqrt(pow(observation1->
x - observation2->
x,2) + pow(observation1->
y - observation2->
y,2));
723 if(distance>x[n-1])
continue;
725 int index = int(distance/(x[1]-x[0]));
726 if(index>n-1) index = n-1;
727 if(index<0) index = 0;
729 gamma[index] += 1./2.*pow(observation1->
value - observation2->
value,2);
730 counter[index] += 1.;
737 if(counter[k]) gamma[k] = gamma[k]/counter[k];
741 xDelete<IssmPDouble>(counter);