您的位置:首页 > 编程语言 > C#

自己用C#写的一个Math类,数学不好,大家帮我看下

2017-10-29 09:50 302 查看
最近一直在用C#写程序,第一次使用C#,项目中有一个评估模块,涉及了一些算法,Math.Net应该都有,只是我不想去找到底用哪个,所以自己根据客户要求,写了一个类,算法公式由于客户提供的,我数学不好,不知道对不对,请大家帮我验证一下,谢谢!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace APSP.Common
{
public static class MathTool
{

/// <summary>
/// 获取相关系数
///
/// ____________________
/// / __
/// / \ N ╭ _ _ ╮
/// / | │(Cm - Cm)×(Co - Co) │
/// / / i=1╰ ╯
/// /  ̄ ̄
/// R = / ――――――――――――――――――――
/// / ____________________
/// / / __ __
/// / / \ N _ \ N _
/// / / | (Cm - Cm)²× | (Co - Co)²
/// / / / i=1 / i=1
/// √ √  ̄ ̄  ̄ ̄
///
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>相关系数R</returns>
public static double Correlation(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double R = 0.0;
double CmAvr = 0.0;
double CoAvr = 0.0;

double CmCoAvrDifProSum = 0.0; //模拟值与平均模拟值的差 和 观测值与平均观测值的差 的乘积和
double CmAvrDifSqSum = 0.0; //模拟值与平均模拟值的差的平方和
double CoAvrDifSqSum = 0.0; //观测值与平均观测值的差的平方和

int n = 0;

CmAvr = Average(Cm);
CoAvr = Average(Co);

using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("Correlation", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo= CoArr.Current;

double CmAvrDif = currCm - CmAvr; //模拟值与平均模拟值的差
double CoAvrDif = currCo - CoAvr; //观测值与平均观测值的差

double CmAvrDifSq = CmAvrDif * CmAvrDif; //模拟值与平均模拟值的差的平方
double CoAvrDifSq = CoAvrDif * CoAvrDif; //观测值与平均观测值的差的平方

CmCoAvrDifProSum += (CmAvrDif * CoAvrDif); //模拟值与平均模拟值的差 和 观测值与平均观测值的差 的乘积和

CmAvrDifSqSum += CmAvrDifSq; //模拟值与平均模拟值的差的平方和
CoAvrDifSqSum += CoAvrDifSq; //观测值与平均观测值的差的平方和
n++;

}
}

R = Math.Sqrt(CmCoAvrDifProSum / Math.Sqrt(CmAvrDifSqSum * CoAvrDifSqSum ));

return R;
}
/// <summary>
/// 求数组内数据的平均值
/// </summary>
/// <param name="data">输入数组</param>
/// <returns>平均值</returns>
public static double Average(IEnumerable<double> data)
{
double varNum = 0.0;
double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> ie = data.GetEnumerator())
{
while (ie.MoveNext())
{
double currentNum = ie.Current;
sumNum += currentNum;
n++;
}
}

varNum = sumNum / n;
return varNum;
}
/// <summary>
/// 求两组数据的平均偏差
/// __
/// 1 \ N
/// MB = ―― | (Cm - Co)×100%
/// N / i=1
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>平均偏差(MB)</returns>
public static double GetMB(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double MB = 0.0;
double CmCoDifSum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetMB", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

CmCoDifSum += (currCm - currCo);
n++;
}
}
MB = CmCoDifSum / n;
return MB;
}
/// <summary>
/// 求两组数据的平均误差
/// __
/// 1 \ N
/// ME = ―― | |Cm - Co|×100%
/// N / i=1
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>平均误差(ME)</returns>
public static double GetME(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double ME = 0.0;

double CmCoDifAbsSum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetME", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

CmCoDifAbsSum += Math.Abs(currCm - currCo);
n++;
}
}
ME = CmCoDifAbsSum / n;
return ME;
}
/// <summary>
/// 求两组数据的相对偏差
/// __
/// 2 \ N (Cm - Co)
/// FB = ―― | ――――― ×100%
/// N / i=1 (Cm + Co)
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>相对偏差(FB)</returns>
public static double GetFB(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double FB = 0
4000
.0;
double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetFB", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += ((currCm - currCo) / (currCm + currCo));

n++;
}
}
FB = sumNum * 2 / n;

return FB;

}

/// <summary>
/// 求两组数据的相对偏差
/// __
/// 2 \ N |Cm - Co|
/// FE = ―― | ――――― ×100%
/// N / i=1 (Cm + Co)
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>相对偏差(FE)</returns>
public static double GetFE(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double FE = 0.0;
double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetFE", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += (Math.Abs(currCm - currCo) / (currCm + currCo));

n++;
}
}
FE = sumNum * 2 / n;

return FE;

}
/// <summary>
/// 求两组数据的平均标准偏差
/// __
/// 1 \ N ╭ Cm - Co ╮
/// MNB = ―― | │――――― │×100%
/// N / i=1╰ Co ╯
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>平均标准偏差(MNB)</returns>
public static double GetMNB(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double MNB = 0.0;
double sumNum = 0.0;
int n = 0;

using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetMNB", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += ((currCm - currCo) / currCo);

n++;
}
}
MNB = sumNum / n;
return MNB;
}
/// <summary>
/// 求两组数据的平均标准误差
/// __
/// 1 \ N | Cm - Co |
/// MNE = ―― | |―――――| ×100%
/// N / i=1 | Co |
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>平均标准误差(MNE)</returns>
public static double GetMNE(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double MNE = 0.0;
double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetMNE", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += Math.Abs((currCm - currCo) / currCo);

n++;
}
}

MNE = sumNum / n;
return MNE;
}

/// <summary>
/// 求两组数据的标准平均偏差
/// __
/// \ N
/// | (Cm - Co)
/// / i=1
///  ̄ ̄
/// NMB = ――――――――― ×100%
/// __
/// \ N
/// | Co
/// / i=1
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>标准平均偏差(NMB)</returns>
public static double GetNMB(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double NMB = 0.0;
double CmCoDifSum = 0.0;
double CoSum = 0.0;
int n = 0;

using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetNMB", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

CmCoDifSum += (currCm - currCo);
CoSum += currCo;
n++;
}
}
NMB = CmCoDifSum / CoSum;
return NMB;
}
/// <summary>
/// 求两组数据的标准平均误差
/// __
/// \ N
/// | |Cm - Co|
/// / i=1
///  ̄ ̄
/// NME = ――――――――― ×100%
/// __
/// \ N
/// | Co
/// / i=1
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>标准平均误差(NME)</returns>
public static double GetNME(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double NME = 0.0;
double CmCoDifSum = 0.0;
double CoSum = 0.0;
int n = 0;

using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetNME", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

CmCoDifSum += Math.Abs(currCm - currCo);
CoSum += currCo;
n++;
}
}
NME = CmCoDifSum / CoSum;
return NME;
}
/// <summary>
/// 求两组数据的平均相对偏差
///
/// MFB = SUM((Cmi-Coi)/(Coi+Cmi/2))/N [i = 1...N]
/// __
/// 1 \ N (Cm - Co)
/// MFB = ―― | ―――――― ×100%
/// N / i=1 (Co + Cm/2)
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>平均相对偏差(MFB)</returns>
public static double GetMFB(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double MFB = 0.0;
double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetNME", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += ((currCm - currCo) / (currCo + (currCm / 2)));

n++;
}
}
MFB = sumNum / n;
return MFB;
}
/// <summary>
/// 求两组数据的平均相对误差
/// __
/// 1 \ N |Cm - Co|
/// MFE = ―― | ―――――― ×100%
/// N / i=1 (Co + Cm/2)
///  ̄ ̄
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>平均相对误差(MFE)</returns>
public static double GetMFE(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double MFE = 0.0;
double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetNME", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += (Math.Abs(currCm - currCo) / (currCo + (currCm / 2)));

n++;
}
}
MFE = sumNum / n;
return MFE;
}
/// <summary>
/// 求两组数据的均方根误差
/// ___________
/// / __
/// / \ N
/// / | (Cm - Co)²
/// / / i=1
/// /  ̄ ̄
/// RMSE = / ―――――――――――
/// / N
/// √
/// Cm:模拟值
/// Co:观测值
/// N :样本个数
/// </summary>
/// <param name="Cm">模拟值</param>
/// <param name="Co">观测值</param>
/// <returns>均方根误差(RMSE)</returns>
public static double GetRMSE(IEnumerable<double> Cm, IEnumerable<double> Co)
{
double RMSE = 0.0;

double sumNum = 0.0;
int n = 0;
using (IEnumerator<double> CmArr = Cm.GetEnumerator())
using (IEnumerator<double> CoArr = Co.GetEnumerator())
{
while (CmArr.MoveNext())
{
if (!CoArr.MoveNext())
{
throw new ArgumentOutOfRangeException("GetNME", "dataB is not consistent with dataA length");
}

double currCm = CmArr.Current;
double currCo = CoArr.Current;

sumNum += ((currCm - currCo) * (currCm - currCo));

n++;
}
}
RMSE = Math.Sqrt(sumNum / n);
return RMSE;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐