github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/spline.go (about) 1 package eeslism 2 3 // 給水温度のスプライン補間 4 5 // 各月の給水温度は15日の給水温度として補間する 6 // Nday:計算対象の通日、Tsupw:1~12月の給水温度 7 var __Intgtsup_ic int = 0 8 9 func Intgtsup(Nday int, Tsupw []float64) float64 { 10 var h, b, d, g, u [13]float64 11 var r, x, y [14]float64 12 var n, Mo int 13 var y1 float64 14 15 if __Intgtsup_ic == 0 { 16 n = 13 17 x[0], x[13] = -15.0, 380.0 18 for Mo = 1; Mo <= 12; Mo++ { 19 x[Mo] = float64(FNNday(Mo, 15)) 20 y[Mo] = Tsupw[Mo-1] 21 y[0], y[13] = Tsupw[11], Tsupw[0] 22 } 23 24 __Intgtsup_ic = 1 25 } 26 27 y1 = spline(n, x[:], y[:], float64(Nday), h[:], b[:], d[:], g[:], u[:], r[:]) 28 return y1 29 } 30 31 /**************************************/ 32 /* 3次スプライン関数による補間 */ 33 /* n : 区間の数 */ 34 /* x, y : 点の座標 */ 35 /* x1 : 補間値を求める値 */ 36 /* h, b, d, g, u, r : 作業域 */ 37 /* return : 補間値 */ 38 /* coded by Y.Suganuma */ 39 /**************************************/ 40 // http://www.sist.ac.jp/~suganuma/kougi/other_lecture/SE/num/spline/C++/spline.txt 41 func spline(n int, x, y []float64, x1 float64, h, b, d, g, u, r []float64) float64 { 42 i, i1, k := -1, 0, 0 43 var y1, qi, si, xx float64 44 45 // 区間の決定 46 for i1 = 1; i1 < n && i < 0; i1++ { 47 if x1 < x[i1] { 48 i = i1 - 1 49 } 50 } 51 if i < 0 { 52 i = n - 1 53 } 54 55 // ステップ1 56 for i1 = 0; i1 < n; i1++ { 57 h[i1] = x[i1+1] - x[i1] 58 } 59 for i1 = 1; i1 < n; i1++ { 60 b[i1] = 2.0 * (h[i1] + h[i1-1]) 61 d[i1] = 3.0 * ((y[i1+1]-y[i1])/h[i1] - (y[i1]-y[i1-1])/h[i1-1]) 62 } 63 64 // ステップ2 65 g[1] = h[1] / b[1] 66 for i1 = 2; i1 < n-1; i1++ { 67 g[i1] = h[i1] / (b[i1] - h[i1-1]*g[i1-1]) 68 } 69 u[1] = d[1] / b[1] 70 for i1 = 2; i1 < n; i1++ { 71 u[i1] = (d[i1] - h[i1-1]*u[i1-1]) / (b[i1] - h[i1-1]*g[i1-1]) 72 } 73 74 // ステップ3 75 if i > 1 { 76 k = i 77 } else { 78 k = 1 79 } 80 r[0] = 0.0 81 r[n] = 0.0 82 r[n-1] = u[n-1] 83 for i1 = n - 2; i1 >= k; i1-- { 84 r[i1] = u[i1] - g[i1]*r[i1+1] 85 } 86 87 // ステップ4 88 xx = x1 - x[i] 89 qi = (y[i+1]-y[i])/h[i] - h[i]*(r[i+1]+2.0*r[i])/3.0 90 si = (r[i+1] - r[i]) / (3.0 * h[i]) 91 y1 = y[i] + xx*(qi+xx*(r[i]+si*xx)) 92 93 return y1 94 }