/// <summary> /// Overload operator + for DPoint /// </summary> /// <param name="d1">Vector d1</param> /// <param name="d2">vector d2</param> /// <returns>sum of d1 & d2</returns> public static DPoint operator +(DPoint d1, DPoint d2) { int d =0 ; d = d1.MyNode.Count; DPoint dp = new DPoint(); dp.MyNode = new List<Node>(); for (int i =0; i<d; ++i) { dp.MyNode.Add(new Node(d1.MyNode[i].Index, d1.MyNode[i].Value + d2.MyNode[i].Value)); } return dp; }
/// <summary> /// Compute Weight of 2 DPoint dp1 and dp2 /// </summary> /// <param name="dp1">DPoint 1</param> /// <param name="dp2">DPoint 2</param> /// <returns>weight of 2 vertex dp1 and dp2</returns> public double Weight(DPoint dp1, DPoint dp2) { return ( Math.Exp( (-1) * Math.Pow(Math.Abs(Distance(dp1,dp2)),2) / ( 2*Xichma*Xichma)) ); }
/// <summary> /// Euclidean distance of DPoint dp1 and dp2 /// </summary> /// <param name="dp1">DPoint 1</param> /// <param name="dp2">DPoint 2</param> /// <returns>distance is Positive if dp1 and dp2 have same label. Distance is Negative if dp1 and dp2 have different label </returns> public static double Distance(DPoint dp1, DPoint dp2) { double x1 = dp1.MyNode[0].Value; double y1 = dp1.MyNode[1].Value; double x2 = dp2.MyNode[0].Value; double y2 = dp2.MyNode[1].Value; if (dp1.Label * dp2.Label > 0) //Same label return (Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2))); else //Different label return (-1) * (Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2))); }
/// <summary> /// Explore all Cluster of Data /// </summary> public void exploreCluster() { int N = _data.Count; kMax = alpha * (int) Log2(N); double distortionMin = double.MaxValue; //Explore Cluster by Sampling technique for (int t = 1; t <= nrSampling; ++t) { int[] cIndex = new int[N]; Dictionary<int, DPoint[]> cluster = new Dictionary<int, DPoint[]>(); List<double> distortion = new List<double>(); //distortion for nrSampling cIndex = samplingData(kMax); //Create cluster and calculate Distortion for (int i = 1; i <= cIndex.Max(); ++i) { List<DPoint> temp = new List<DPoint>(); DPoint avg = new DPoint(); double avgDistortion = 0; //Create cluster for (int j = 0; j < N; ++j) if (cIndex[j] == i) temp.Add(_data.Data[j]); cluster.Add(i, temp.ToArray()); if (temp.Count == 0) continue; //Calculate Distortion avg = temp[0]/temp.Count; for (int j = 1; j < temp.Count; ++j) avg = avg + temp[j]/temp.Count; //Calculate avgDistortion foreach (DPoint dp in temp) avgDistortion += Distance(dp, avg); distortion.Add(avgDistortion); } double sum = distortion.Sum(); if ( sum < distortionMin) { distortionMin = sum; myClusters = cluster; } } }
/// <summary> /// Euclidean distance of DPoint dp1 and dp2 /// </summary> /// <param name="dp1">DPoint 1</param> /// <param name="dp2">DPoint 2</param> /// <returns>distance is Positive if dp1 and dp2 have same label. Distance is Negative if dp1 and dp2 have different label </returns> public static double Distance(DPoint dp1, DPoint dp2) { double x1 = dp1.MyNode[0].Value; double y1 = dp1.MyNode[1].Value; double x2 = dp2.MyNode[0].Value; double y2 = dp2.MyNode[1].Value; return(Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2))); }
/// <summary> /// Constructor /// </summary> /// <param name="_data">your data here</param> public Dataset(DPoint[] _data) { Data = _data; Count = Data.Length; }
/// <summary> /// Read a Dataset from a Stream /// </summary> /// <param name="stream">Stream to Read</param> /// <returns>The Dataset</returns> private static Dataset Read(Stream stream) { StreamReader reader = new StreamReader(stream); //LibSVM Variable List<DPoint> data = new List<DPoint>(); int max_index = 0; while (!reader.EndOfStream) { DPoint dataLine = new DPoint(); List<Node> X = new List<Node>(); string[] tmp = reader.ReadLine().Split(' '); for (int i = 0; i < tmp.Length; ++i) if (tmp[i] == "") tmp = tmp.Where(w => w != tmp[i]).ToArray(); int m = tmp.Length - 1; Node[] x = new Node[m]; dataLine.Label = double.Parse(tmp[0]); for (int i = 0; i < m; ++i) { string[] t = tmp[i + 1].Split(':'); x[i] = new Node(); x[i].Index = int.Parse(t[0]); x[i].Value = double.Parse(t[1]); } dataLine.MyNode = x.ToList(); if (m > 0) max_index = Math.Max(max_index, x[m - 1].Index); data.Add(dataLine); } return new Dataset(data.ToArray()); }
public static DPoint operator /(DPoint d1, double num) { int d = d1.MyNode.Count; DPoint dp = new DPoint(); dp.MyNode = new List<Node>(); for (int i = 0; i < d; ++i) { dp.MyNode.Add(new Node(d1.MyNode[i].Index, (double)d1.MyNode[i].Value/num)); } return dp; }