我想用 Linq 表达下面的公式
我有以下功能
private double Calc(IEnumerable<Frequency> recording, IEnumerable<Frequency> reading)
{
}
在哪里Frequency
:
public class Frequency
{
public double Probability { get; set; } //which are p's and q's in the formula
public int Strength { get; set; } //the i's i the formula
}
对该函数的示例调用是
public void Caller(){
IEnumerable<Frequency> recording = new List<Frequency>
{
new Frequency {Strength = 32, Probability = 0.2}, //p32 = 0.2
new Frequency {Strength = 33, Probability = 0.2}, //p33 = 0.2
new Frequency {Strength = 34, Probability = 0.2}, //p34 = 0.2
new Frequency {Strength = 35, Probability = 0.2}, //...
new Frequency {Strength = 41, Probability = 0.2} //...
};
IEnumerable<Frequency> reading = new List<Frequency>
{
new Frequency {Strength = 34, Probability = 0.2}, //q34 = 0.2
new Frequency {Strength = 35, Probability = 0.2}, //q35 = 0.2
new Frequency {Strength = 36, Probability = 0.2},
new Frequency {Strength = 37, Probability = 0.2},
new Frequency {Strength = 80, Probability = 0.2},
};
Calc(reading, recordig);
}
例如,new Frequency {Strength = 32, Probability = 0.2},
表示p32 = 0.2
在 Hellinger 公式中。
k
公式中将为 100,如果集合中不存在元素,则其值为 0。例如,记录仅具有 i = 32,33, 34,35,41 的值,因此对于 1-100 pi 中的其他值将为零。
我的第一个实现是
private double Calc(IEnumerable<Frequency> recording, IEnumerable<Frequency> reading)
{
double result = 0;
foreach (var i in Enumerable.Range(1,100))
{
var recStr = recording.FirstOrDefault(a => a.Strength == i);
var readStr = reading.FirstOrDefault(a => a.Strength == i);
var recVal = recStr == null ? 0 : recStr.Probability;
var readVal = readStr == null ? 0 : readStr.Probability;
result += Math.Pow(Math.Sqrt(recVal) - Math.Sqrt(readVal), 2);
}
result = Math.Sqrt(result/2);
return result;
}
这既不高效也不优雅。我觉得解决方案可以改进,但我想不出更好的方法。