Skip to content

Commit fd97e71

Browse files
author
linzhijun
committed
使用 Welford 算法 优化代码
1 parent 17af64a commit fd97e71

6 files changed

Lines changed: 34 additions & 40 deletions

File tree

csharp/ToolGood.Algorithm/Internals/Functions/MathSum/Function_COVAR.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,15 @@ public override Operand Evaluate(AlgorithmEngine engine, Func<AlgorithmEngine, s
2828
if (list1.Count != list2.Count) { return Operand.Error("Function '{0}' parameter's count error!", "Covar"); }
2929
if (list1.Count == 0) { return Operand.Error("Function '{0}' parameter's count error!", "Covar"); }
3030

31-
decimal sum1 = 0, sum2 = 0;
32-
for (int i = 0; i < list1.Count; i++) { sum1 += list1[i]; sum2 += list2[i]; }
33-
var avg1 = sum1 / list1.Count;
34-
var avg2 = sum2 / list1.Count;
35-
decimal sum = 0;
31+
decimal mean1 = 0, mean2 = 0, c = 0;
3632
for (int i = 0; i < list1.Count; i++) {
37-
sum += (list1[i] - avg1) * (list2[i] - avg2);
33+
decimal delta1 = list1[i] - mean1;
34+
decimal delta2 = list2[i] - mean2;
35+
mean1 += delta1 / (i + 1);
36+
mean2 += delta2 / (i + 1);
37+
c += delta1 * (list2[i] - mean2);
3838
}
39-
var val = sum / list1.Count;
40-
return Operand.Create(val);
39+
return Operand.Create(c / list1.Count);
4140
}
4241

4342
}

csharp/ToolGood.Algorithm/Internals/Functions/MathSum/Function_COVARIANCES.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,15 @@ public override Operand Evaluate(AlgorithmEngine engine, Func<AlgorithmEngine, s
3030
if (list1.Count != list2.Count) { return Operand.Error("Function '{0}' parameter's count error!", "CovarIanceS"); }
3131
if (list1.Count == 1) { return Operand.Error("Function '{0}' parameter's count error!", "CovarIanceS"); }
3232

33-
decimal sum1 = 0, sum2 = 0;
34-
for (int i = 0; i < list1.Count; i++) { sum1 += list1[i]; sum2 += list2[i]; }
35-
var avg1 = sum1 / list1.Count;
36-
var avg2 = sum2 / list1.Count;
37-
decimal sum = 0;
33+
decimal mean1 = 0, mean2 = 0, c = 0;
3834
for (int i = 0; i < list1.Count; i++) {
39-
sum += (list1[i] - avg1) * (list2[i] - avg2);
35+
decimal delta1 = list1[i] - mean1;
36+
decimal delta2 = list2[i] - mean2;
37+
mean1 += delta1 / (i + 1);
38+
mean2 += delta2 / (i + 1);
39+
c += delta1 * (list2[i] - mean2);
4040
}
41-
var val = sum / (list1.Count - 1);
42-
return Operand.Create(val);
41+
return Operand.Create(c / (list1.Count - 1));
4342
}
4443

4544
}

csharp/ToolGood.Algorithm/Internals/Functions/MathSum/Function_DEVSQ.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ public override Operand Evaluate(AlgorithmEngine engine, Func<AlgorithmEngine, s
2121
var o = FunctionUtil.F_base_GetList(args, list);
2222
if (o == false) { return FunctionError(); }
2323
if (list.Count == 0) { return FunctionError(); }
24-
decimal sum = 0;
25-
foreach (var item in list) { sum += item; }
26-
var avg = sum / list.Count;
27-
decimal sum2 = 0;
24+
decimal mean = 0, m2 = 0;
2825
for (int i = 0; i < list.Count; i++) {
29-
sum2 += (list[i] - avg) * (list[i] - avg);
26+
decimal delta = list[i] - mean;
27+
mean += delta / (i + 1);
28+
m2 += delta * (list[i] - mean);
3029
}
31-
return Operand.Create(sum2);
30+
return Operand.Create(m2);
3231
}
3332

3433
}

csharp/ToolGood.Algorithm/Internals/Functions/MathSum/Function_STDEV.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ public override Operand Evaluate(AlgorithmEngine engine, Func<AlgorithmEngine, s
2222
if (o == false) { return FunctionError(); }
2323
if (list.Count == 0) { return FunctionError(); }
2424

25-
double sum = 0;
26-
foreach (var item in list) { sum += item; }
27-
var avg = sum / list.Count;
28-
double sum2 = 0;
25+
double mean = 0, m2 = 0;
2926
for (int i = 0; i < list.Count; i++) {
30-
sum2 += (list[i] - avg) * (list[i] - avg);
27+
double delta = list[i] - mean;
28+
mean += delta / (i + 1);
29+
m2 += delta * (list[i] - mean);
3130
}
32-
return Operand.Create(Math.Sqrt(sum2 / (list.Count - 1)));
31+
return Operand.Create(Math.Sqrt(m2 / (list.Count - 1)));
3332
}
3433

3534
}

csharp/ToolGood.Algorithm/Internals/Functions/MathSum/Function_STDEVP.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ public override Operand Evaluate(AlgorithmEngine engine, Func<AlgorithmEngine, s
2121
var o = FunctionUtil.F_base_GetList(args, list);
2222
if (o == false) { return FunctionError(); }
2323
if (list.Count == 0) { return FunctionError(); }
24-
double sum = 0;
25-
foreach (var item in list) { sum += item; }
26-
var avg = sum / list.Count;
27-
double sum2 = 0;
24+
double mean = 0, m2 = 0;
2825
for (int i = 0; i < list.Count; i++) {
29-
sum2 += (list[i] - avg) * (list[i] - avg);
26+
double delta = list[i] - mean;
27+
mean += delta / (i + 1);
28+
m2 += delta * (list[i] - mean);
3029
}
31-
return Operand.Create(Math.Sqrt(sum2 / list.Count));
30+
return Operand.Create(Math.Sqrt(m2 / list.Count));
3231
}
3332

3433
}

csharp/ToolGood.Algorithm/Internals/Functions/MathSum/Function_VARP.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ public override Operand Evaluate(AlgorithmEngine engine, Func<AlgorithmEngine, s
2424
if (list.Count == 0) { return FunctionError(); }
2525
if (list.Count == 1) { return Operand.Zero; }
2626

27-
decimal sum = 0;
28-
foreach (var item in list) { sum += item; }
29-
decimal avg = sum / list.Count;
30-
decimal sum2 = 0;
27+
decimal mean = 0, m2 = 0;
3128
for (int i = 0; i < list.Count; i++) {
32-
sum2 += (avg - list[i]) * (avg - list[i]);
29+
decimal delta = list[i] - mean;
30+
mean += delta / (i + 1);
31+
m2 += delta * (list[i] - mean);
3332
}
34-
return Operand.Create(sum2 / list.Count);
33+
return Operand.Create(m2 / list.Count);
3534
}
3635

3736
}

0 commit comments

Comments
 (0)