MathNet.Numerics是一个.NET的开源数学库,包含了.NET平台上的面向对象数字计算的基础类。类似 NMath ,但 NMath 是收费的。
开源地址:
目前版本为V4.15
https://github.com/mathnet/mathnet-numerics
API详细说明包
https://download.csdn.net/download/zyyujq/82935441
Combinatorics 排列组合相关功能
ComplexExtensions 对System.Numerics类中复数相关功能的扩展
Constants 数学中常用的一些常数。
ContourIntegrate 对库的参数进行配置。
Differentiate 导数,对函数求一阶导数和二阶导数等。
Distance 各种类型的距离计算。
Euclid 整数数论。
Evaluate 多项式评价函数,类似于Matlab中Polyval。
ExcelFunctions excel 中常用的函数,仅作为从excel转移到MathNet的过渡,不推荐正式使用。
FindMinimum 极小值迭代器。
FindRoots 方程求根。
Fit 使用最小二乘算法拟合数据。
支持直线、多项式、指数等多种函数拟合。
Generate 生成器:斐波那契数列、线性数组、正态分布等常用的数据。
GoodnessOfFit 对拟合结果进行评价。
Integrate 数值积分。
Interpolate 各类插值算法。
Permutation 数值排列?
Polynomial 多项式函数相关。
Precision 对浮点数据的操作,浮点数值对比等。
Sorting 模板函数,排序。
SpecialFunctions 特殊的函数
TestFunctions 一些特殊的函数,可用来测试其他功能。
Trig 双精度的三角函数。
Window 滤波算法子定义。
统计量分析:
若需要计算样本参数的统计量特征分析,可以直接调用Statistics类的扩展方法,也可以将样本传递给DescriptiveStatistics的构造函数一次性计算出全部特性。
代码1是使用DescriptiveStatistics的例程:
using MathNet.Numerics.Statistics;
//ChiSquare创建X~2检验样本,这里的样本值可以换成自己的样本集
var samples = new ChiSquare(5).Samples().Take(1000);
var statistics = new DescriptiveStatistics(samples);
// 最大值,最小值,中位数
var largestElement = statistics.Maximum;
var smallestElement = statistics.Minimum;
var median = statistics.Median;
// 平均数
var mean = statistics.Mean;
// 方差,标准差
var variance = statistics.Variance;
var stdDev = statistics.StandardDeviation;
// 峭度,不对称度
var kurtosis = statistics.Kurtosis;
var skewness = statistics.Skewness;
代码2是使用扩展方法的例程:
using MathNet.Numerics.Statistics;
// 扩展方法是基于 IEnumerable定义的
// 所以需要调用ToArray做一下转化
var samples = new ChiSquare(5).Samples().Take(1000).ToArray()
;
// Order Statistics
var largestElement = samples.Maximum();
var smallestElement = samples.Minimum();
var median = samples.Median();
var 250thOrderStatistic = samples.OrderStatistic(250);
// Central Tendency
var mean = samples.Mean();
// Dispersion
var variance = samples.Variance();
var biasedPopulationVariance = samples.PopulationVariance();
var stdDev = samples.StandardDeviation();
var biasedPopulationStdDev = samples.
PopulationStandardDeviation();
线性代数
关于线性代数的计算位于命名空间MathNet.Numerics.LinearAlgebra下,该命名空间下有四个子命名空间。
MathNet.Numerics.LinearAlgebra.Double:双精度浮点数计算
MathNet.Numerics.LinearAlgebra.Single:单精度浮点数计算
MathNet.Numerics.LinearAlgebra.Complex:进行复杂的双精度浮点数计算
MathNet.Numerics.LinearAlgebra.Complex32:进行复杂的单精度浮点数计算
之所以分为四个子命名空间的原因是考虑了内存需求,双精度浮点矩阵至少需要4倍同样单精度浮点矩阵的内存。此外,好考虑了矩阵的存储情况,现在Math.net支持三种矩阵的存储:
DenseMatrix: 任意矩阵
SparseMatrix: 稀疏矩阵
DiagonalMatrix:对角阵
将矩阵分为这三种也也考虑了对应存储的优化,比如稀疏矩阵在存储时就使用了3数组的稀疏压缩行(Compressed-sparse-row, CSR)格式。
代码3是矩阵乘以向量的例程:
using MathNet.Numerics.LinearAlgebra.Double;
// Create a vector of dimension 5 with 4.0 in every entry.
var x = new DenseVector(5, 4.0);
// Create a 3 by 5 matrix with 2.0 in every entry.
var A = new DenseMatrix(3, 5, 2.0);
// Multiply the matrix and the vector.
var y = A * x;
//注意:var来自名称空间System,只能定义在局部变量,不能定义在全局变量
//1、矩阵的定义和初始化
var matrix1 = new DenseMatrix(3);//3维方阵
var matrix2 = new DenseMatrix(2,2); //2维方阵
var matrix3 = new DenseMatrix(2, 3); //2×3矩阵
var matrix4 = new DenseMatrix(3, 2); //3×2矩阵
var matrix5= new DenseMatrix(2, 3, 3.0); //2×3矩阵,所有值为3.0
var matrixI = DenseMatrix.Identity(5); //5维单位矩阵
//利用C#中的double[,]直接创建,2×3矩阵
double[,] d_matrix = new double[2, 3];
var matrix6 = new DenseMatrix(d_matrix);
//3维方阵
var matrix2 = new DenseMatrix(3);
//2*3矩阵
var matrix3 = new DenseMatrix(2, 3);
//5维单位矩阵
var matrixI = DenseMatrix.CreateIdentity(5);
richTextBox1.AppendText(matrixI.ToMatrixString());//直接输出矩阵
richTextBox1.AppendText(matrixI.ToString());//在矩阵输出之前会有一段描述
//可以利用C#中的double[,]创建=====》对应着下图1
double[,] d_matrix =
{
{11,12,13,14,15,16 },
{21,22,23,24,25,26 },
{31,32,33,34,35,36 },
{41,42,43,44,45,46 },
{51,52,53,54,55,56 },
{61,62,63,64,65,66 }
};
var matrix1 = DenseMatrix.OfArray(d_matrix);
richTextBox1.AppendText(matrix1.ToString());//输出显示
//显示结果:
//DenseMatrix 6x6-Double
//11,12,13,14,15,16
//21,22,23,24,25,26
//31,32,33,34,35,36
//41,42,43,44,45,46
//51,52,53,54,55,56
//61,62,63,64,65,66
//2、矩阵的操作
//取从第二行开始的2行,第三列开始的三列 子矩阵
var submatrix = matrix2.SubMatrix(2, 2, 3, 3);
//显示结果:(以上例数据展示)
//DenseMatrix 2x3-Double
//34 35 36
//44 45 46
var row = matrix2.Row(5, 3, 4); //取从第5行第3列开始的4个行元素
var column = matrix2.Column(2, 6, 3); //取从第2列第6行开始的3个列元素
var columndata = matrix2.ColumnEnumerator(2, 4); //取从第2列开始的4列
var rowdata = matrix2.RowEnumerator(4, 3);//取从第4行开始的3行
var data1 = matrix2.ToRowWiseArray();//矩阵变为行向量
var data2 = matrix2.ToColumnWiseArray();//矩阵变为列向量
var data3 = matrix2.Diagonal()//取矩阵的对角线元素向量
var row = matrix.Row(2, 3, 3);//取从第2行第3列开始的3个行元素
//显示结果:(以上例数据展示)
//DenseMatrix 3-Double
//34
//35
//36
//取从第2列第3行开始的3个列元素
var col = matrix.Column(2, 3, 3);
//显示结果:(以上例数据展示)
//DenseMatrix 3-Double
//43
//53
//63
//取矩阵的对角线元素向量
var m4 = matrix.Diagonal();
//显示结果:(以上例数据展示)
//DenseMatrix 6-Double
//11
//22
//33
//44
//55
//66
//将向量vector插入到指定的行 / 列,原有的行列顺延
double[] d_vector = { 0, 0, 0, 0, 0, 0};
var vector = new DenseVector(d_vector);
var result = matrix.InsertColumn(3, vector);
var result = matrix.InsertRow(3, vector);
//PS:插入的向量长度必须和矩阵的行数或列数一样
//显示结果:(以上例数据展示)
//DenseMatrix 6x7-Double
//11 12 13 0 14 15 16
//21 22 23 0 24 25 26
//31 32 33 0 34 35 36
//41 42 43 0 44 45 46
//51 52 53 0 54 55 56
//61 62 63 0 64 65 66
//用vector替换指定的行 / 列
matrix.SetColumn(2, (Vector)vector);
matrix.SetRow(3, (double[])vector);
//显示结果:(以上例数据展示)
//DenseMatrix 6x7-Double
//11 12 0 14 15 16
//21 22 0 24 25 26
//31 32 0 34 35 36
//41 42 0 44 45 46
//51 52 0 54 55 56
//61 62 0 64 65 66
//用矩阵替换指定位置的块矩阵
matrix.SetSubMatrix(1, 3, 1, 3, DenseMatrix.CreateIdentity(3));
//DenseMatrix 6x6-Double
//11 12 13 14 15 16
//21 1 0 0 25 26
//31 0 1 0 35 36
//41 0 0 1 45 46
//51 52 53 54 55 56
//61 62 54 64 65 66
//替换矩阵的对角线元素
matrix.SetDiagonal(new[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 });
//将matrixB扩展到matrix的右方 / 上方,将结果保存在result中
matrix.Append(matrixB, result);
matrix.Stack(matrixB, result);
//PS:矩阵的大小必须严格设置,matrixB的行数或列数必须和matrix的也一样
//互换矩阵的3,4行
var permutations = new MathNet.Numerics.Permutation(new[] { 0, 1, 3, 2, 4,5 });
matrix.PermuteRows(permutations);
//互换矩阵的1、2列,3、5列
var permutations = new MathNet.Numerics.Permutation(new[] { 1, 0, 4, 3, 2, 5 });
matrix.PermuteColumns(permutations);
//3、矩阵的运算
//点乘
var result = mA.PointwiseMultiply(mB);
//求逆
var mB = mA.Inverse();
//求解线性方程组,其中m1对应系数矩阵
var m = m1.LU().Solve(m2);
//PS:以下代码只作记录,还未验证!
//行列式
var m = m1.Determinant()
//秩
var m = m1.Rank();
//条件数
var m = m1.ConditionNumber();
//Trace
var m = m1.Trace();
//范数
var m = m1.L1Norm()/L2Norm()/FrobeniusNorm()/InfinityNorm();
特殊函数
阶乘:Factorial
对数阶乘:FactorialLn
伯努利系数:Binomial
对数伯努利系数:BinomialLn
多项式系数:Multinomial
代码4 阶乘例程:
using MathNet.Numerics;
double x = SpecialFunctions.Factorial(2);
// x will now have the value 2
double y = SpecialFunctions.Factorial(4);
// y will now have the value 24
其他特殊函数如Gamma, Logistic
函数插值
函数插值位于命名空间MathNet.Numerics.Interpolation。
Math.net的插值有两种:
为选定算法和样本点创建一个插值结构,你将获得一个实现了IInterpolation接口的类。
使用该插值结构计算任意位置的点。一些插值算法还可以计算偏差和不定积分。
静态类Interpolate提供了工厂方法来创建插值操作:
RationalWithoutPoles:创建 Floater-Hormann重心插值
RationalWithPoles:创建Bulirsch& Stoer有理插值
LinearBetweenPoints:创建样条曲线插值
如果不确定使用哪种插值方法,我们推荐使用Floater-Hormann重心插值。或者,你也可以直接使用别的插值算法,它们都位于子命名空间Algorithms ,下面是一些插值算法:
等间距样本点插值:
Polynomial: 重心算法,多项式插值
任意样本点插值:
· Rational pole-free:Floater-Hormann重心算法
· Rational with poles: Bulirsch & Stoer算法
· Neville Polynomial: Neville算法。注意 Neville算法在处理等间距样本点时非常低效。.如果需要在等间距样本点上进行多项式插值,推荐使用barycentric算法。
· Linear Spline:样条曲线
· Cubic Spline 带边界条件的三次样条曲线
· Natural Cubic Spline:普通三次样条曲线
· Akima Cubic Spline:akima三次样条曲线
其他数据插值:
· Generic Barycentric Interpolation,需要barycentric权重
· Generic Spline,需要样条系数
· Generic Cubic Hermite Spline,需要偏差
代码5 插值例程:
using MathNet.Numerics.Signals;
using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// 1. 利用函数1/(1+x*x) 在区间 [-5, 5]产生10个样本点
//points是x坐标,values是y坐标值
Console.WriteLine(@"1. Generate 10 samples of the
function 1/(1+x*x) on interval [-5, 5]");
double[] points;
var values = SignalGenerator.EquidistantInterval(
TargetFunction, -5, 5, 10, out points);
Console.WriteLine();
// 2. Create a floater hormann rational pole-free
interpolation based on arbitrary points
// This method is used by default when create an
interpolation using Interpolate.Common method
var method = Interpolate.RationalWithoutPoles(points,
values);
Console.WriteLine(@"2. Create a floater hormann
rational pole-free interpolation based on arbitrary
points");
Console.WriteLine();
// 3. 是否支持积分
Console.WriteLine(@"3. Support integration = {0}",
method.SupportsIntegration);
Console.WriteLine();
// 4. 是否支持微分
Console.WriteLine(@"4. Support differentiation = {0}
", method.SupportsDifferentiation);
Console.WriteLine();
// 5. 将插值结果和函数计算结果做比较
Console.WriteLine(@"5. Interpolate ten random points
and compare to function results");
var rng = new MersenneTwister(1);
for (var i = 0; i < 10; i++)
{
// Generate random value from [0, 5]
var point = rng.NextDouble() * 5;
Console.WriteLine(@"Interpolate at {0} = {1}.
Function({0}) = {2}", point.ToString("N05"),
method.Interpolate(point).ToString("N05"),
TargetFunction(point).ToString("N05"));
}
Console.ReadKey();
}
public static double TargetFunction(double x)
{
return 1 / (1 + (x * x));
}
}
}
线性积分变换
math.net目前仅支持两种线性积分变换:离线傅立叶变换和离散哈特莱变换。它们都仅能在频域下进行变换,但傅立叶变换支持复杂数值,而哈特莱变换仅支持实数值。它们都支持正变换和反变换,这是靠方法中的options参数来区分的。
傅立叶空间:离散傅立叶变换DFT和快速傅立叶变换FFT
目前支持的算法有:
· Naive Discrete Fourier Transform (DFT): Out-placetransform for arbitrary vector lengths. Mainly intended for verifying fasteralgorithms: NaiveForward, NaiveInverse
· Radix-2 Fast Fourier Transform (FFT): In-placefast fourier transform for vectors with a power-of-two length (Radix-2): Radix2Forward, Radix2Inverse
· Bluestein Fast Fourier Transform (FFT): In-placefast fourier transform for arbitrary vector lengths:BluesteinForward, BluesteinInverse
另外,Transform类提供了静态方法使我们能更容易地使用傅立叶正变换FourierForward和傅立叶反变换FourierInverse。如代码6所示。
// create a complex sample vector of length 96
Complex[] samples = SignalGenerator.EquidistantInterval(
t => new Complex(1.0 / (t * t + 1.0),
t / (t * t + 1.0)),
-16, 16, 96);
// inplace bluestein FFT with default options
Transform.FourierForward(samples);
下面是一些傅立叶参数,原文没有翻译:
· Default: Uses a negative exponent sign inforward transformations, and symmetric scaling (that is, sqrt(1/N) for bothforward and inverse transformation). This is the convention used in Maple andis widely accepted in the educational sector (due to the symmetry).
· AsymmetricScaling: Set this flag to suppress scalingon the forward transformation but scale the inverse transform with 1/N.
· NoScaling: Set this flag to suppress scaling forboth forward and inverse transformation. Note that in this case if you applyfirst the forward and then inverse transformation you won’t get back theoriginal signal (by factor N/2).
· InverseExponent: Uses the positive instead of thenegative sign in the forward exponent, and the negative (instead of positive)exponent in the inverse transformation.
· Matlab: Use this flag if you need Matlab compatibility.Equals to setting the AsymmetricScaling flag.This matches the definition used in the wikipedia article.
· NumericalRecipes: Use this flag if you needNumerical Recipes compatibility. Equal to setting both theInverseExponent and the NoScaling flags.
下面是一些傅立叶变换有用的常识,就是讲变换前后的奇偶性,很容易看懂:
· h(t) is real valued <=> real part of H(f) is even,imgainary part of H(f) is odd
· h(t) is imaginary valued <=> real part of H(f) isodd, imaginary part of H(f) is even
· h(t) is even <=> H(f) is even
· h(t) is odd <=> H(f) is odd
· h(t) is real-valued even <=> H(f) is real-valuedeven
· h(t) is real-valued odd <=> H(f) isimaginary-valued odd
· h(t) is imaginary-valued even <=> H(f) isimaginary-valued even
· h(t) is imaginary-valued odd <=> H(f) isreal-valued odd
Math.Abs(x) x绝对值,已重载。返回指定数字的绝对值。
Math.Acos(x) 余弦值为x的角度,返回余弦值为指定数字的角度。
Math.Asin(x) 正弦值为x的角度,返回正弦值为指定数字的角度。
Math.Atan(x) 正切值为x的角度,返回正切值为指定数字的角度。
Math.Atan2(x, y) 正切值为 x y 的商的角度,返回正切值为两个指定数字的商的角度。
Math.BigMul(x, y) x,y 的完整乘积,生成两个 32 位数字的完整乘积。
Math.Ceiling(x) >= x的最小整数,已重载。返回大于或等于指定数字的最小整数。
Math.Cos(x) 角度为x的余弦值,返回指定角度的余弦值。
Math.Cosh(x) 角度为x的双曲余弦值,返回指定角度的双曲余弦值。
Math.DivRem(x, y, out z) x除以y的整数值 并返回余数z,已重载。计算两个数字的商,并在输出参数中返回余数。
Math.E 自然对数的底数 e = 2.718…,
Math.Exp(x) e的x次幂,返回 e 的指定次幂。
Math.Floor(x) <= x(x为小数)的最小整数,已重载。返回小于或等于指定数字的最大整数。
Math.IEEERemainder(x, y) y除以x的余数,返回一指定数字被另一指定数字相除的余数。
Math.Log(x) x的自然对数,已重载。返回指定数字的对数。
Math.Log10(x) x以10为底的对数,返回指定数字以 10 为底的对数。
Math.Max(x, y) x,y中比较大的数值,已重载。返回两个指定数字中较大的一个。
Math.Min(x, y) x,y中比较小的数值,已重载。返回两个数字中较小的一个。
Math.PI 常量 π 圆周长与直径的比,
Math.Pow(x, y) x的y次方,返回指定数字的指定次幂。
Math.Round(x) x四舍五入的值,已重载。将值舍入到最接近的整数或指定的小数位数。
Math.Sign() 已重载。返回表示数字符号的值。
Math.Sin(x) 角度为x的正弦值,返回指定角度的正弦值。
Math.Sinh(x) 角度为x的双曲正弦值,返回指定角度的双曲正弦值。
Math.Sqrt(x) x的平方根,返回指定数字的平方根。
Math.Tan(x) 角度为x的正切值,返回指定角度的正切值。
Math.Tanh(x) 角度为x的双曲正切值,返回指定角度的双曲正切值。
Math.Truncate(x) 小数x的整数部分,已重载。计算一个数字的整数部分。
Equals 已重载。确定两个 Object 实例是否相等。 (从 Object 继承。)
ReferenceEquals 确定指定的 Object 实例是否是相同的实例。 (从 Object 继承。)
GetHashCode 用作特定类型的哈希函数。GetHashCode 适合在哈希算法和数据结构(如哈希表)中使用。 (从 Object 继承。)
GetType 获取当前实例的 Type。 (从 Object 继承。)
ToString 返回表示当前 Object 的 String。 (从 Object 继承。)
1、向上进位取整。Math.Ceiling
例如: Math.Ceiling(32.6)=33; Math.Ceiling(32.0)=32;
2、向下舍位取整。Math.Floor
例如: Math.Floor(32.6)=32;
3、取指定位数的小数。Math.Round
例如:Math.Round(36.236,2)=36.24; Math.Round(36.232,2)=36.23;
4、取指定数字在使用指定底时的对数。Math.Log
例如:一本16开的书,计算对开了几次。Math.Log(16,2)=4;
名称 说明
E 表示自然对数的底,它由常数 e 指定。
PI 表示圆的周长与其直径的比值,它通过常数 π 指定。
命名空间
Math.NET Numerics
Math.NET Numerics是核心功能是数值计算。主要是提供日常科学工程计算相关的算法,包括一些特殊函数,线性代数,概率论,随机函数,微积分,插值,最优化等相关计算功能。它是在 Math.NET Iridium和dnAnalytics 的基础上合并而来。该组件里面包括了一个读取Matlab数据格式的功能,我们将在后几篇博客中加以介绍。
支持概率分布:离散型、连续型和多元
伪随机数生成器
支持稀疏矩阵和向量的复杂的线性代数解决方法
LU, QR, SVD, EVD,Cholesky分解
矩阵读写功能,支持Matlab和一些分开的文件
复数计算
特殊函数: Gamma, Beta, Erf,Bessel,Struve 等等
插值,线性回归,曲线拟合
数值积分,方程求解
描述性统计、统计直方图,皮尔森相关系数
马尔可夫链蒙特卡罗抽样
基本的财务统计数据
傅里叶变换(FFT)
重载的数学操作符来简化复杂的表达式
Mono平台支持,可选支持英特尔数学内核库(Microsoft Windows和Linux)
可选更多的的F#扩展用法
Math.NET Symbolics
Math.NET Symbolics是一个Math.NET下一个基础的代数计算项目,该项目的最终目的并不是要成为如Maple,Mathematica那样一个完善的计算机代数计算系统。以前在做Matlab.NET混合编程的时候,经常就有人问为什么混合编程的符号计算用不了,其实就是用不了,官方不支持,那怎么办,其实简单的功能,就可以使用这个项目来完成。
Math.NET Filtering
Math.NET Filtering是一个数字信号处理工具箱,提供了数字滤波器的基础功能,以及滤波器应用到数字信号处理和数据流转换的相关功能。
Math.NET Spatial
是Math.NET下的一个几何处理工具箱。
其他
Math.NET在发展过程中的一些其他项目如Math.NET Iridium ,Math.NET Classic, Math.NET Linq Algebra, Math.NET Yttrium等都是历史(有一些是实验性的),现在都已经合并到上述几个子项目中。