我有一个带累计值的List,point有一个日期和3个值。第一次测量为零。
我正在尝试获取每个月的第一个值。
知道点数(月/日)
1/10/2008 0.000
1/12/2008 0.201
1/2/2009 0.403
1/4/2009 0.604
1/6/2009 0.810
1/8/2009 1.023
1/10/2009 1.234
1/12/2009 1.453
1/1/2010 1.677
1/2/2010 1.892
1/4/2010 2.117
1/6/2010 2.342
1/8/2010 2.569
1/10/2010 2.798
1/12/2010 3.032
1/2/2011 3.255
1/4/2011 3.487
1/6/2011 3.720
1/8/2011 3.954
1/10/2011 4.189
1/12/2011 4.428
1/2/2012 4.661
1/4/2012 4.898
1/6/2012 5.135
1/8/2012 5.373
1/10/2012 5.612
1/12/2012 5.855
1/2/2013 6.087
1/4/2013 6.327
1/6/2013 6.568
1/8/2013 6.809
1/10/2013 7.051
1/12/2013 7.297
1/2/2014 7.531
1/4/2014 7.774
1/6/2014 8.017
1/8/2014 8.260
1/10/2014 8.504
1/12/2014 8.752
1/2/2015 8.988
1/4/2015 9.233
1/6/2015 9.478
1/8/2015 9.723
1/10/2015 9.968
1/12/2015 10.218
1/2/2016 10.460
1/4/2016 10.706
1/6/2016 10.953
1/8/2016 11.199
1/10/2016 11.446
1/12/2016 11.698
1/2/2017 11.937
1/4/2017 12.185
1/6/2017 12.433
1/8/2017 12.681
1/10/2017 12.929
1/12/2017 13.182
1/2/2018 13.422
1/4/2018 13.671
1/6/2018 13.921
1/8/2018 14.170
预期结果
10/1/2008 0
11/1/2008 0.102
12/1/2008 0.201
1/1/2009 0.302
2/1/2009 0.403
3/1/2009 0.498
4/1/2009 0.604
5/1/2009 0.705
6/1/2009 0.81
7/1/2009 0.915
8/1/2009 1.023
9/1/2009 1.131
10/1/2009 1.234
11/1/2009 1.345
12/1/2009 1.453
1/1/2010 1.565
2/1/2010 1.677
3/1/2010 1.779
4/1/2010 1.892
5/1/2010 2.003
6/1/2010 2.117
7/1/2010 2.228
8/1/2010 2.342
9/1/2010 2.458
10/1/2010 2.569
11/1/2010 2.686
12/1/2010 2.798
1/1/2011 2.915
2/1/2011 3.032
3/1/2011 3.138
4/1/2011 3.255
5/1/2011 3.369
6/1/2011 3.487
7/1/2011 3.602
8/1/2011 3.72
9/1/2011 3.839
10/1/2011 3.954
11/1/2011 4.073
12/1/2011 4.189
1/1/2012 4.308
2/1/2012 4.428
3/1/2012 4.54
4/1/2012 4.661
5/1/2012 4.777
6/1/2012 4.897
7/1/2012 5.014
8/1/2012 5.135
9/1/2012 5.256
10/1/2012 5.373
11/1/2012 5.495
12/1/2012 5.612
1/1/2013 5.734
2/1/2013 5.855
3/1/2013 5.965
4/1/2013 6.087
5/1/2013 6.205
6/1/2013 6.327
7/1/2013 6.446
8/1/2013 6.568
9/1/2013 6.691
10/1/2013 6.809
11/1/2013 6.932
12/1/2013 7.051
1/1/2014 7.174
2/1/2014 7.297
3/1/2014 7.408
4/1/2014 7.531
5/1/2014 7.65
6/1/2014 7.774
7/1/2014 7.893
8/1/2014 8.017
9/1/2014 8.14
10/1/2014 8.26
11/1/2014 8.384
12/1/2014 8.504
1/1/2015 8.628
2/1/2015 8.752
3/1/2015 8.864
4/1/2015 8.988
5/1/2015 9.108
6/1/2015 9.233
7/1/2015 9.353
8/1/2015 9.478
9/1/2015 9.602
10/1/2015 9.723
11/1/2015 9.848
12/1/2015 9.968
1/1/2016 10.093
2/1/2016 10.218
3/1/2016 10.335
4/1/2016 10.46
5/1/2016 10.581
6/1/2016 10.706
7/1/2016 10.827
8/1/2016 10.953
9/1/2016 11.078
10/1/2016 11.199
11/1/2016 11.325
12/1/2016 11.446
1/1/2017 11.572
2/1/2017 11.698
3/1/2017 11.811
4/1/2017 11.937
5/1/2017 12.059
6/1/2017 12.185
7/1/2017 12.307
8/1/2017 12.433
9/1/2017 12.559
10/1/2017 12.681
11/1/2017 12.807
12/1/2017 12.929
1/1/2018 13.055
2/1/2018 13.182
3/1/2018 13.296
4/1/2018 13.422
5/1/2018 13.545
6/1/2018 13.671
7/1/2018 13.794
8/1/2018 13.92
9/1/2018 14.047
10/1/2018 14.17
我正在尝试进行线性插值,但值不匹配。也许我做错了什么。
你能帮忙找到我错过的东西吗?
这是我的代码
public List<Cum> Interpolate() {
List<Cum> result = new List<Cum>();
Cum firstCum = this.Cums.First();
Cum lastCum = this.Cums.Last();
//warn if first date is nonzero
if (firstCum.O > 0) Msg.alert("Warning! Starting rates are nonzero");
//0. add data point at the end of known points if last kp is not beginning of month. i.e. 11/7/2018 -> 12/01/2018
DateTime nextLastDate = lastCum.T.AddMonths(1);
if (lastCum.T.Day > 1) this.Cums.Add(new Cum(new DateTime(nextLastDate.Year, nextLastDate.Month, 1), lastCum.O));
//1. Add missing data points
int knownPoints = this.Cums.Count - 1;
DateTime firstDate = this.Cums.First().T;
DateTime nextMonthDate = new DateTime(firstDate.Year, firstDate.AddMonths(1).Month, 1);
for (int i = 0; i <= knownPoints; i++) {
DateTime aDate = new DateTime(this.Cums[i].T.Year, this.Cums[i].T.Month, 1);
//if date is not missing, do not interpolate
if (aDate < nextMonthDate) {
//remove duplicate from results (this is first of month, so it's a good one)
if (this.Cums[i].T.Day == 1) result.Remove(result.Last());
result.Add(this.Cums[i]);
//if first of month is missing, add new data point and interpolate
} else {
//before and after datapoints
int p1 = i - 1 < 0 ? 0 : i - 1;
int p2 = i + 1 > knownPoints ? i : i + 1;
float x0 = this.Cums[p1].T.Year + this.Cums[p1].T.DayOfYear;
float x1 = this.Cums[p2].T.Year + this.Cums[p2].T.DayOfYear;
float y0 = this.Cums[p1].O;
float y1 = this.Cums[p2].O;
//Linear Interpolation
//DateTime T = new DateTime(this.Cums[i].T.Year, this.Cums[i].T.Month, 1);
float x = nextMonthDate.Year + nextMonthDate.DayOfYear;
//float x = T.Year + this.Cums[p1].T.DayOfYear;
float O = (float)linear(x, x0, x1, y0, y1);
//first date should have zero cummulative;
if (i == 0) O = G = W = 0;
result.Add(new Cum(new DateTime(nextMonthDate.Year, nextMonthDate.Month, 1), O));
nextMonthDate = nextMonthDate.AddMonths(1);
i--;
}
}
return result;
}
static public double linear(double x, double x0, double x1, double y0, double y1) {
if ((x1 - x0) == 0) {
return (y0 + y1) / 2;
}
return y0 + (x - x0) * (y1 - y0) / (x1 - x0);
}