github.com/pavlo67/common@v0.5.3/common/mathlib/interpolation.go (about) 1 package mathlib 2 3 import ( 4 "fmt" 5 "sort" 6 ) 7 8 const onInterpolateByTable = "on numlib.InterpolateByTable()" 9 10 func InterpolateByTable(x float64, xy [][2]float64) (float64, error) { 11 if len(xy) < 1 { 12 return 0, fmt.Errorf(onInterpolateByTable + ": table is empty") 13 } 14 15 sort.Slice(xy, func(i, j int) bool { return xy[i][0] < xy[j][0] }) 16 for i := 0; i < len(xy); i++ { 17 if x == xy[i][0] { 18 return xy[i][1], nil 19 } else if x < xy[i][0] { 20 if i == 0 { 21 return 0, fmt.Errorf(onInterpolateByTable+": x (%f) is smaller than tha first table argument (%f)", x, xy[0][0]) 22 } 23 24 // TODO: if xy[i][0] == xy[i-1][0] && xy[i][1] != xy[i-1][1] 25 return xy[i-1][1] + (x-xy[i-1][0])*(xy[i][1]-xy[i-1][1])/(xy[i][0]-xy[i-1][0]), nil 26 } 27 } 28 29 return 0, fmt.Errorf(onInterpolateByTable+": x (%f) is greater than tha last table argument (%f)", x, xy[len(xy)-1][0]) 30 } 31 32 const onInterpolateByTwoPoints = "on numlib.InterpolateByTwoPoints()" 33 34 func InterpolateByTwoPoints(x float64, xy [2][2]float64) (float64, error) { 35 if xy[0][0] < xy[1][0] { 36 if x < xy[0][0] || x > xy[1][0] { 37 return 0, fmt.Errorf("onInterpolateBetweenTwoPoints: target x (%f) isn't between x0 (%f) and x1 (%f)", x, xy[0][0], xy[1][0]) 38 } 39 } else { 40 if x > xy[0][0] || x < xy[1][0] { 41 return 0, fmt.Errorf("onInterpolateBetweenTwoPoints: target x (%f) isn't between x0 (%f) and x1 (%f)", x, xy[0][0], xy[1][0]) 42 } else if xy[1][0] == xy[0][0] { 43 // TODO: if xy[1][1] != xy[0][1] 44 return xy[0][1], nil 45 } 46 } 47 48 return xy[0][1] + (x-xy[0][0])*(xy[1][1]-xy[0][1])/(xy[1][0]-xy[0][0]), nil 49 }