public static List <Gaussian_2D> fit(List <Vector2> pts_init, int num_clusters_init) { pts = pts_init; num_clusters = num_clusters_init; int num_points = pts.Count(); List <Gaussian_2D> gau_list = new List <Gaussian_2D>(); int iter_counter = 0; init_centroid = random_state.choice(pts, num_clusters); List <int> closest_centroid = new List <int>(); List <Vector2> centroid = init_centroid; List <Vector2> old_centroid = init_centroid; do { old_centroid = centroid; closest_centroid = ClosestCentroid(old_centroid); centroid = ShiftCentroid(closest_centroid); iter_counter++; } while (!CloseCentroid(old_centroid, centroid) && iter_counter <= 50); foreach (Vector2 miu in centroid) { Gaussian_2D gau = new Gaussian_2D(rand, miu); gau_list.Add(gau); } return(gau_list); }
public static List <Gaussian_2D> fit(List <Vector2> pts_init, int num_clusters_init) { pts = pts_init; num_clusters = num_clusters_init; int num_points = pts.Count(); int iter_counter = 0; List <Gaussian_2D> gau_list = new List <Gaussian_2D>(); List <List <double> > membership = InitializeMemberships(); //List<List<double>> old_membership = new List<List<double>>(); List <Vector2> centers = UpdateCenter(membership); List <Vector2> old_centres = new List <Vector2>(); do { iter_counter++; //old_membership = membership; old_centres = centers; membership = UpdateMemberships(centers); centers = UpdateCenter(membership); } while (!CloseCentroid(old_centres, centers) && iter_counter <= 50); foreach (Vector2 miu in centers) { Gaussian_2D gau = new Gaussian_2D(rand, miu); gau_list.Add(gau); } return(gau_list); }
/// <summary> /// Initialize and add new gaussians at the beginning of each level /// </summary> /// <param name="level"> /// Level index /// </param> private void InitLevel(int level, int init_type) { Console.WriteLine("level {0} begin ", level); List <Gaussian_2D> level_gaussian_list = new List <Gaussian_2D>(); //TODO: initialize gaussians at smaller scale for deeper levels, only within the parent domain //gau.Sigma.m00 /= level + 1; //gau.Sigma.m11 /= level + 1; if (init_type == 0 || init_type == 1) // kmeans_init (0) || FCM_init (1) { level_gaussian_list = ClusteringInitGMM(level, init_type); } else if (init_type == 2) { IEnumerable <int> level_gaussian_idx = GetLevel(level); foreach (int i in level_gaussian_idx) { //Each gaussian is randomly initialized at four corners Gaussian_2D gaussian_rand = new Gaussian_2D(rand, (i % 8) + 1, true); level_gaussian_list.Add(gaussian_rand); } } foreach (Gaussian_2D gaussian in level_gaussian_list) { gaussian_list.Add(gaussian); //All gaussians at each level are initialized with equal class prior class_prior.Add(1 / (double)(num_gaussian)); //A list of constitute sufficient statistics for updating gaussian parameters in parallel. //See paper section 3.5 T.Add(new List <double>(new double[] { 0, 0, 0, 0, 0, 0, 0 })); } }
public static (List <Vector2>, List <Gaussian_2D>) Generate(int num_of_points, int num_gaussians) { List <Gaussian_2D> ground_truth_gaussian_list = new List <Gaussian_2D>(); List <Vector2> pts = new List <Vector2>(); Random rand = new Random(); int ptsPerGaussian = (int)Math.Round((double)num_of_points / num_gaussians); for (int loop = 0; loop < num_gaussians; loop++) { Gaussian_2D sample_gaussian = new Gaussian_2D(rand); ground_truth_gaussian_list.Add(sample_gaussian); sample_gaussian.Sigma.UpdateEigens(); double angle; if (sample_gaussian.Sigma.m00 > sample_gaussian.Sigma.m11) { angle = Math.Atan2(sample_gaussian.Sigma.eigenvector_0.y, sample_gaussian.Sigma.eigenvector_0.x); } else { angle = Math.Atan2(sample_gaussian.Sigma.eigenvector_1.y, sample_gaussian.Sigma.eigenvector_1.x); } double u1, u2; int x_old, y_old; int x, y; for (int i = 0; i < ptsPerGaussian; i++) { do { u1 = rand.NextDouble(); u2 = rand.NextDouble(); } while (u1 == 0 && u2 == 0); x_old = (int)Math.Round(Math.Sqrt(sample_gaussian.Sigma.m00) * Math.Sqrt(-2 * Math.Log(u2)) * Math.Cos(2 * Math.PI * u1)); y_old = (int)Math.Round(Math.Sqrt(sample_gaussian.Sigma.m11) * Math.Sqrt(-2 * Math.Log(u2)) * Math.Sin(2 * Math.PI * u1)); x = (int)Math.Round(x_old * Math.Cos(angle) - y_old * Math.Sin(angle) + sample_gaussian.miu.x); y = (int)Math.Round(x_old * Math.Sin(angle) + y_old * Math.Cos(angle) + sample_gaussian.miu.y); pts.Add(new Vector2(x, y)); } } return(pts, ground_truth_gaussian_list); }
private void Draw3SigmaEllipse(Graphics g, Gaussian_2D gaussian, Pen pen) { gaussian.Sigma.UpdateEigens(); float major_axis, minor_axis; if (gaussian.Sigma.eigenvalue_0 > gaussian.Sigma.eigenvalue_1) { major_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_0)); minor_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_1)); } else { major_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_1)); minor_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_0)); } float x_axis, y_axis; double angle; if (gaussian.Sigma.m00 > gaussian.Sigma.m11) { x_axis = major_axis; y_axis = minor_axis; angle = Math.Atan2(gaussian.Sigma.eigenvector_0.y, gaussian.Sigma.eigenvector_0.x); } else { x_axis = minor_axis; y_axis = major_axis; angle = Math.Atan2(gaussian.Sigma.eigenvector_1.y, gaussian.Sigma.eigenvector_1.x); } if (Double.IsNaN(angle)) { label_status.Text = "One or more gaussians failed to fit. Modify your input parameters."; return; } g.TranslateTransform(gaussian.miu.x, gaussian.miu.y); g.RotateTransform((float)(angle * 180 / Math.PI)); //Rad to Deg g.DrawEllipse(pen, new RectangleF(-(int)Math.Round(x_axis / 2), -(int)Math.Round(y_axis / 2), x_axis, y_axis)); g.ResetTransform(); }
/// <summary> /// Calculate multivariate normal probablity density function. /// Hardcoded for Vector2 and Matrix22 datatype. /// Use double precision to increase robustness. /// </summary> /// <param name="pt"></param> /// <param name="miu"></param> /// <param name="covariance"></param> /// <returns></returns> private static double MultiNormalPDF(Vector2 pt, Gaussian_2D gaussian) { Vector2 miu = gaussian.miu; Matrix22 covariance = gaussian.Sigma; Vector2 x_minus_miu = pt.Minus(miu); Matrix22 inv_cov = covariance.Inverse(); //Break Matrix22 into two rows (Vector2) for dot product Vector2 row1 = new Vector2(inv_cov.m00, inv_cov.m01); Vector2 row2 = new Vector2(inv_cov.m10, inv_cov.m11); float dot_row1 = row1.Dot(x_minus_miu); float dot_row2 = row2.Dot(x_minus_miu); //Assemble two rows Vector2 temp_v = new Vector2(dot_row1, dot_row2); double numerator = Math.Exp(-x_minus_miu.Dot(temp_v) / 2); double denom = 2 * Math.PI * Math.Sqrt(covariance.Det()); return(numerator / denom); }
private List <Gaussian_2D> ClusteringInitGMM(int level, int init_type) { List <Gaussian_2D> cluster_list = new List <Gaussian_2D>(); if (level != 0) { IEnumerable <int> parent_level_gaussians = GetLevel(level - 1); foreach (int i in parent_level_gaussians) { List <Vector2> parent_pts = new List <Vector2>(); List <Gaussian_2D> cluster_list_i = new List <Gaussian_2D>(); foreach (Vector2 pt in pts) { if (pt.gaussian_idx[level - 1] == i) { parent_pts.Add(pt); } } //if there are fewer points than num_gaussian * 2 in the parent gaussian, stop partition //if (parent_pts.Count <= num_gaussian * 2 || gaussian_list[i].partition == false) if (parent_pts.Count < num_gaussian || gaussian_list[i].partition == false) { Console.WriteLine("===========Stopping at gaussian {0}==============", i); //gaussian_list[i].partition = false; for (int j = 0; j < num_gaussian; j++) { Gaussian_2D gau = new Gaussian_2D(); gau.partition = false; gau.dropped = true; cluster_list_i.Add(gau); } cluster_list = cluster_list.Concat(cluster_list_i).ToList(); if (parent_pts.Count > 2 && gaussian_list[i].dropped == false) { BaseModel lineModel = new LineModel(); lineModel = RANSAC.Fit(parent_pts, lineModel, 2, 2.00F); baseModels.Add(lineModel); } continue; } if (init_type == 1) { cluster_list_i = FuzzyCMeans.fit(parent_pts, num_gaussian); } else if (init_type == 0) { cluster_list_i = KMeans.fit(parent_pts, num_gaussian); } cluster_list = cluster_list.Concat(cluster_list_i).ToList(); } } else { if (init_type == 1) { cluster_list = FuzzyCMeans.fit(pts, num_gaussian); } else if (init_type == 0) { cluster_list = KMeans.fit(pts, num_gaussian); } } return(cluster_list); }