討論一下C#面向集合的擴(kuò)展
我們知道有很多數(shù)學(xué)軟件,如MatLab是面向矩陣的,而開(kāi)源語(yǔ)言R是面向向量的,SQL是面向關(guān)系系的、APL(Array processing language)是一種一種多用途、第三代(3GL)編程語(yǔ)言,在向量、矩陣等各種秩的數(shù)組處理上非常簡(jiǎn)單。SPSS,SAS等都需要大量的集合運(yùn)算。
本文試圖從C#本身的特性出發(fā),模擬C#面向集合的方法。
更期望C#面向集合能向MatLab, APL,R那樣直接處理集合運(yùn)算,進(jìn)入科學(xué)和工程計(jì)算領(lǐng)域,為以后的并行計(jì)算奠定基礎(chǔ)。
有一列觀測(cè)值,用List存儲(chǔ),我們現(xiàn)在需要求出每一個(gè)觀測(cè)值的正弦Sin值。
用C#面向過(guò)程的語(yǔ)法表示如下:
- List list2;
 - for (int i = 0; i < list2.Count; i++)
 - list2[i] = Math.Sin(list2[i]);
 
求Sin值,是一個(gè)繁瑣而又重復(fù)的問(wèn)題。我們希望Math.Sin(Collection c),在不改變已有代碼(不擴(kuò)展Math.Sin)的情況下,自動(dòng)處理集合,就像在MatLab里面。
C#是面向過(guò)程的,而Matlab是面向矩陣的,SQL是面向關(guān)系代數(shù)的。關(guān)系代數(shù)和矩陣,都可以看作集合的特例。(LINQ部分加入了面向集合的特性)
面向過(guò)程,需要程序員書(shū)寫(xiě)算法的每一個(gè)過(guò)程和細(xì)節(jié),指明執(zhí)行路徑,這主要表現(xiàn)在循環(huán)語(yǔ)句的使用上(包括for, foreach, while…)。
面向過(guò)程給了程序員最充分的自由和最大的靈活,但其固有的“底層”,導(dǎo)致了開(kāi)發(fā)效率的底下,同時(shí)不利于并行計(jì)算和系統(tǒng)優(yōu)化。而在數(shù)學(xué)中,大部分計(jì)算都是基于矩陣(集合),例如圖形圖像處理,概率論,數(shù)理統(tǒng)計(jì),優(yōu)化控制等等。 所以C#難以勝任運(yùn)算集中和知識(shí)處理,人工智能設(shè)計(jì)。
由于C#實(shí)在是太優(yōu)美,是目前最藝術(shù)的語(yǔ)言,利用C#現(xiàn)有特性,我們可以簡(jiǎn)單的模擬前面提出的問(wèn)題
- public static List Apply(Converter f, List l)
 - {
 - List list2 = new List(l);
 - for (int i = 0; i < list2.Count; i++)
 - list2[i] = Math.Sin(list2[i]);
 - for (int i = 0; i < l.Count; i++)
 - {
 - list2[i] = f(l[i]);
 - }
 - return list2;
 - }
 
這樣,我們可以在Apply來(lái)處理一些關(guān)于集合處理的問(wèn)題。
下面在給出一個(gè)處理矩陣的例子:
- public static Matrix Apply(Converter f, Matrix m)
 - {
 - Matrix m2 = new Matrix(m);
 - for (int i = 0; i < m.Row; i++)
 - for (int j = 0; j < m.Col; j++)
 - m2[i, j] = f(m2[i, j]);
 - return m2;
 - }
 
使用這個(gè)Apply,可以處理矩陣集合相關(guān)的計(jì)算。
矩陣定義如下: 
- public class Matrix
 - {
 - public double[,] data;
 - public Matrix(int row, int col)
 - {
 - data = new double[row, col];
 - }
 - //復(fù)制構(gòu)造函數(shù)
 - public Matrix(Matrix m)
 - {
 - data = (double[,])m.data.Clone();
 - }
 - public int Col
 - {
 - get
 - {
 - return data.GetLength(1);
 - }
 - }
 - // 行數(shù)
 - public int Row
 - {
 - get
 - {
 - return data.GetLength(0);
 - }
 - }
 - //重載索引
 - //存取數(shù)據(jù)成員
 - public virtual double this[int row, int col]
 - {
 - get
 - {
 - return data[row, col];
 - }
 - set
 - {
 - data[row, col] = value;
 - }
 - }
 - //維數(shù)
 - public int Dimension
 - {
 - get { return 2; }
 - }
 - public string ToString(int prec)
 - {
 - StringBuilder sb = new StringBuilder();
 - string format = "{0:F" + prec.ToString() + "} ";
 - for (int i = 0; i < Row; i++)
 - {
 - for (int j = 0; j < Col - 1; j++)
 - {
 - sb.Append(string.Format(format, data[i, j]));
 - }
 - sb.Append(data[i, Col - 1]);
 - sb.Append(""n");
 - }
 - return sb.ToString();
 - }
 - }
 
再看下面復(fù)數(shù)的例子:
- public static List Apply(Converter< Complex,double> f, List l)
 - {
 - List l2 = new List(l.Count);
 - for (int i = 0; i < l.Count; i++)
 - l2.Add(f(l[i]));
 - return l2;
 - }
 
使用這個(gè)Apply,可以處理復(fù)數(shù)集合相關(guān)的許多計(jì)算。
復(fù)數(shù)類(lèi)的定義如下:
- Code
 - public class Complex:ICloneable
 - {
 - private double real;
 - /**////
 - /// 復(fù)數(shù)的實(shí)部
 - ///
 - public double Real
 - {
 - get { return real; }
 - set { real = value; }
 - }
 - private double image;
 - /**////
 - /// 復(fù)數(shù)的虛部
 - ///
 - public double Image
 - {
 - get { return image; }
 - set { image = value; }
 - }
 - /**////
 - /// 默認(rèn)構(gòu)造函數(shù)
 - ///
 - public Complex()
 - : this(0, 0)
 - {
 - }
 - /**////
 - /// 只有實(shí)部的構(gòu)造函數(shù)
 - ///
 - /// 實(shí)部
 - public Complex(double real)
 - : this(real, 0) { }
 - /**////
 - /// 由實(shí)部和虛部構(gòu)造
 - ///
 - /// 實(shí)部
 - /// 虛部
 - public Complex(double r, double i)
 - {
 - rreal = r;
 - iimage = i;
 - }
 - /**////重載加法
 - public static Complex operator +(Complex c1, Complex c2)
 - {
 - return new Complex(c1.real + c2.real, c1.image + c2.image);
 - }
 - /**////重載減法
 - public static Complex operator -(Complex c1, Complex c2)
 - {
 - return new Complex(c1.real - c2.real, c1.image - c2.image);
 - }
 - /**////重載乘法
 - public static Complex operator *(Complex c1, Complex c2)
 - {
 - return new Complex(c1.real * c2.real - c1.image * c2.image, c1.image * c2.real + c1.real * c2.image);
 - }
 - /**////
 - /// 求復(fù)數(shù)的模
 - ///
 - /// 模
 - public double Modul
 - {
 - get
 - {
 - return Math.Sqrt(real * real + image * image);
 - }
 - }
 - public static double Sin(Complex c)
 - {
 - return c.image / c.Modul;
 - }
 - /**////
 - /// 重載ToString方法
 - ///
 - /// 打印字符串
 - public override string ToString()
 - {
 - if (Real == 0 && Image == 0)
 - {
 - return string.Format("{0}", 0);
 - }
 - if (Real == 0 && (Image != 1 && Image != -1))
 - {
 - return string.Format("{0} i", Image);
 - }
 - if (Image == 0)
 - {
 - return string.Format("{0}", Real);
 - }
 - if (Image == 1)
 - {
 - return string.Format("i");
 - }
 - if (Image == -1)
 - {
 - return string.Format("- i");
 - }
 - if (Image < 0)
 - {
 - return string.Format("{0} - {1} i", Real, -Image);
 - }
 - return string.Format("{0} + {1} i", Real, Image);
 - }
 - ICloneable 成員#region ICloneable 成員
 - public object Clone()
 - {
 - Complex c = new Complex(real, image);
 - return c;
 - }
 - #endregion
 - }
 
從前面三個(gè)例子,我們可以看出,C#面向集合有多種表示方式,有.net框架中的List,也有自定義的Matrix,同時(shí)集合的元素也是多種數(shù)據(jù)類(lèi)型,有系統(tǒng)中的值類(lèi)型,也有自定義的復(fù)數(shù)Complex類(lèi)型。
當(dāng)然這種算法過(guò)于勉強(qiáng),顯然不是我們所需要的。
我們需要的是一個(gè)在不更改現(xiàn)有語(yǔ)言的情況下,不擴(kuò)充Math.Sin函數(shù)(試著想想有多少個(gè)類(lèi)似的函數(shù),Cos, Tan, 我們自己定義的各種函數(shù))。系統(tǒng)自動(dòng)處理集合。也就是說(shuō),對(duì)于函數(shù)    public delegate TOutput Converter
【編輯推薦】















 
 
 

 
 
 
 