private double Interpolate1D(PValue _pv) { if (_pv == null) { return(double.NaN); } PValue pv1, pv2; this.FindNearestNeighbors(_pv, out pv1, out pv2); // check the neighbors bool neighb_not_same = PValue.InGeneralPosition1D(pv1, pv2); if (neighb_not_same) { // interpolate double f1, f2; PValue.GetLinearCoords(pv1, pv2, _pv, out f1, out f2); if (this.CanInterpolate) { return(f1 * this.table[pv1] + f2 * this.table[pv2]); } else { return((f1 > f2) ? this.table[pv1] : this.table[pv2]); } } else { // the neighbors are the same -> we are out of bounds return(this.table[pv1]); } }
public double this[PValue index] { get { if (!this.IsValid) { return(double.NaN); } if (this.table.ContainsKey(index)) { return(this.table[index]); } else { return(this.RetrieveValue(index)); } } set { if (this.IsValid && this.table.ContainsKey(index)) { this.table[index] = value; } } }
private void FindNearestNeighbors(PValue _pv, out PValue _pvSmaller, out PValue _pvBigger, out PValue _pv3) { int n = this.table.Count; int counter = -1; foreach (var entry in this.table) { counter++; if (entry.Key >= _pv) { break; } } _pvSmaller = this.table.ElementAt(counter).Key; if (counter == 0 || counter == n - 1) { // A. out of range _pvBigger = this.table.ElementAt(counter).Key; _pv3 = null; return; } else { _pvBigger = this.table.ElementAt(counter + 1).Key; } // B. find a third point for an interpolation triangle // order the table values according to distance from the query value _pv SortedList <PValue, double> sorted_acc_to_dist = new SortedList <PValue, double>(new PValueDistComparer(_pv)); foreach (var entry in this.table) { if (entry.Key == _pvSmaller || entry.Key == _pvBigger) { continue; } sorted_acc_to_dist.Add(entry.Key, entry.Value); } // find closest value that builds a triangle around the query value _pv foreach (var entry in sorted_acc_to_dist) { if (PValue.IsInsideTriangle(_pvSmaller, _pvBigger, entry.Key, _pv, true)) { _pv3 = entry.Key; return; } } // C. no well-defined triangle could be found // if none could be found, leave the third point empty _pv3 = null; }
private double RetrieveValue(PValue _pv) { if (_pv == null) { return(double.NaN); } if (_pv.Dim == ParameterValueDim.DIM_1) { return(this.Interpolate1D(_pv)); } else if (_pv.Dim == ParameterValueDim.DIM_2) { return(this.Interpolate2D(_pv)); } else { return(this.table.ElementAt(0).Value); } }
private double Interpolate2D(PValue _pv) { if (_pv == null) { return(double.NaN); } PValue pv1, pv2, pv3; this.FindNearestNeighbors(_pv, out pv1, out pv2, out pv3); // check the neighbors if (pv3 == null) { // 1D interpolation return(Interpolate1D(_pv)); } else { // 2D interpolation if (this.CanInterpolate) { double f1, f2, f3; PValue.GetBarycentricCoords(pv1, pv2, pv3, _pv, out f1, out f2, out f3); return(f1 * this.table[pv1] + f2 * this.table[pv2] + f3 * this.table[pv3]); } else { SortedList <PValue, double> sorted_neighb = new SortedList <PValue, double>(new PValueDistComparer(_pv)); sorted_neighb.Add(pv1, this.table[pv1]); sorted_neighb.Add(pv2, this.table[pv2]); sorted_neighb.Add(pv3, this.table[pv3]); return(sorted_neighb.ElementAt(0).Value); } } }
private void FindNearestNeighbors(PValue _pv, out PValue _pvSmaller, out PValue _pvBigger) { int n = this.table.Count; int counter = -1; foreach (var entry in this.table) { counter++; if (entry.Key >= _pv) { break; } } _pvSmaller = this.table.ElementAt(counter).Key; if (counter == 0 || counter == n - 1) { _pvBigger = this.table.ElementAt(counter).Key; } else { _pvBigger = this.table.ElementAt(counter + 1).Key; } }