//--------------------------------------------------------------------- public static void Initialize() { PlugIn.ModelCore.UI.WriteLine(" Initializing dispersal kernel..."); dispersal_probability = new Dictionary <double, double>(); //cumulative_dispersal_probability = new Dictionary<double, Dictionary<double, double>>(); //Key 1 = direction, Key2 = distance cumulative_dispersal_probability = new List <Triplet>(); cum_prob_benchmarks = new Dictionary <double, int>(); cum_prob_benchmarks_tail = new Dictionary <double, int>(); cum_prob_benchmarks_tail2 = new Dictionary <double, int>(); dispersalIndex = new List <int>(); dispersalDir = new List <double>(); dispersalDist = new List <double>(); dispersalProb = new List <double>(); double max_dispersal_distance = max_dispersal_window(); max_dispersal_distance_pixels = (int)(max_dispersal_distance / PlugIn.ModelCore.CellLength); dispersal_probability.Clear(); cumulative_dispersal_probability.Clear(); double total_p = 0; double cumulative_p = 0; int index = 0; Dictionary <double, int> dispersal_prob_count = new Dictionary <double, int>();; for (int x = 0; x <= max_dispersal_distance_pixels; x++) // (int x = -all_species[s].max_dispersal_distance_pixels; x <= all_species[s].max_dispersal_distance_pixels; x++) { for (int y = x; y <= max_dispersal_distance_pixels; y++) // (int y = -all_species[s].max_dispersal_distance_pixels; y <= all_species[s].max_dispersal_distance_pixels; y++) { double dx, dy, r, p, dir; dx = PlugIn.ModelCore.CellLength * x; dy = PlugIn.ModelCore.CellLength * y; r = Math.Sqrt(dx * dx + dy * dy); p = dispersal_prob(x, y); dir = Math.Asin(dy / r); if (r == 0) { dir = 0; } if (x == 0 && y == 0) { cumulative_p += p; total_p += p; Triplet myTriplet = new Triplet(dir, r, cumulative_p); cumulative_dispersal_probability.Add(myTriplet); dispersalIndex.Add(index); index++; dispersalDir.Add(dir); dispersalDist.Add(r); dispersalProb.Add(cumulative_p); } else if (x == y || x == 0 || y == 0) { total_p += 4 * p; for (int i = 0; i <= 3; i++) { cumulative_p += p; double myDir = dir + i * (Math.PI / 2); Triplet myTriplet = new Triplet(myDir, r, cumulative_p); cumulative_dispersal_probability.Add(myTriplet); dispersalIndex.Add(index); index++; dispersalDir.Add(dir); dispersalDist.Add(r); dispersalProb.Add(cumulative_p); } } else { total_p += 8 * p; for (int i = 0; i <= 7; i++) { cumulative_p += p; double myDir = dir + i * (Math.PI / 4); Triplet myTriplet = new Triplet(myDir, r, cumulative_p); cumulative_dispersal_probability.Add(myTriplet); dispersalIndex.Add(index); index++; dispersalDir.Add(dir); dispersalDist.Add(r); dispersalProb.Add(cumulative_p); } } if (dispersal_probability.ContainsKey(r)) { dispersal_probability[r] += p; dispersal_prob_count[r]++; } else { dispersal_probability.Add(r, p); dispersal_prob_count.Add(r, 1); } /*if(cumulative_dispersal_probability.ContainsKey(dir)) * { * cumulative_dispersal_probability[dir].Add(r, cumulative_p); * } * else{ * Dictionary<double,double> cum_disp_prob_dir = new Dictionary<double,double>(); * cum_disp_prob_dir.Add(r, cumulative_p); * cumulative_dispersal_probability.Add(dir,cum_disp_prob_dir); * } * */ } } indexArray = dispersalIndex.ToArray(); double dispersalProbMax = dispersalProb.Max(); List <double> dispersalProbAdj = dispersalProb.Select(r => r / dispersalProbMax).ToList(); dispersalProbAdj[dispersalProbAdj.Count() - 1] = 1; probArray = dispersalProbAdj.ToArray(); //double cumulative_prob = 0; foreach (double r in dispersal_prob_count.Keys) { dispersal_probability[r] = dispersal_probability[r] / dispersal_prob_count[r]; //cumulative_prob += dispersal_probability[r]; //cumulative_dispersal_probability[r] = cumulative_prob; } double mark = 0.001; double mark_tail_start = 0.997001; double mark_tail = mark_tail_start; double mark_tail2_start = 0.99999701; double mark_tail2 = mark_tail2_start; int cumProbIndex = 0; foreach (Triplet myTriplet in cumulative_dispersal_probability) { if ((myTriplet.Prob >= mark) && (myTriplet.Prob < mark_tail_start)) { cum_prob_benchmarks.Add(mark, cumProbIndex); mark = Math.Round((mark + 0.001) * 1000) / 1000; } if ((myTriplet.Prob >= mark_tail) && (myTriplet.Prob < mark_tail2_start)) { cum_prob_benchmarks_tail.Add(mark_tail, cumProbIndex); mark_tail = Math.Round((mark_tail + 0.000001) * 1000000) / 1000000; } if (myTriplet.Prob >= mark_tail2) { cum_prob_benchmarks_tail2.Add(mark_tail2, cumProbIndex); mark_tail2 = Math.Round((mark_tail2 + 0.00000001) * 100000000) / 100000000; if (mark_tail2 >= 1.0000000000000) { break; } } cumProbIndex++; } /* * // For testing purposes * string path1 = "C:/BRM/LANDIS_II/GitCode/Extension-SpruceBudworm/test/benchmarks.csv"; * string path2 = "C:/BRM/LANDIS_II/GitCode/Extension-SpruceBudworm/test/benchmarks_tail.csv"; * string path3 = "C:/BRM/LANDIS_II/GitCode/Extension-SpruceBudworm/test/benchmarks_tail2.csv"; * String csvBenchmarks = String.Join(Environment.NewLine, cum_prob_benchmarks.Select(d => d.Key.ToString() + "," + d.Value.ToString()).ToArray()); * String csvBenchmarksTail = String.Join(Environment.NewLine, cum_prob_benchmarks_tail.Select(d => d.Key.ToString() + "," + d.Value.ToString()).ToArray()); * String csvBenchmarksTail2 = String.Join(Environment.NewLine, cum_prob_benchmarks_tail2.Select(d => d.Key.ToString() + "," + d.Value.ToString()).ToArray()); * System.IO.File.WriteAllText(path1, csvBenchmarks); * System.IO.File.WriteAllText(path2, csvBenchmarksTail); * System.IO.File.WriteAllText(path3, csvBenchmarksTail2); * */ }
public static void DisperseLDDSpeedUp(Site site, bool wrapLDD, double lddEdgeWrapReduction) { //var s1 = Stopwatch.StartNew(); int disperseCount = (int)Math.Round(SiteVars.LDDout[site]); if (disperseCount > 0) { //PlugIn.ModelCore.UI.WriteLine("Site: " + site.ToString() + " LDD Dispersed: " + disperseCount.ToString()); List <Pair> disperseList = new List <Pair>(); PlugIn.ModelCore.ContinuousUniformDistribution.Alpha = 0; PlugIn.ModelCore.ContinuousUniformDistribution.Beta = 1; double randNum = PlugIn.ModelCore.ContinuousUniformDistribution.NextDouble(); List <double> randList = new List <double>(); for (int i = 1; i <= disperseCount; i++) { randNum = PlugIn.ModelCore.ContinuousUniformDistribution.NextDouble(); randList.Add(randNum); } randList.Sort(); int randIndex = 0; int probIndex = 0; while (randIndex < randList.Count) { double randValue = randList[randIndex]; int tempProbIndex = probIndex; if (randValue > cumulative_dispersal_probability[cumulative_dispersal_probability.Count() - 1].Prob) { probIndex = cumulative_dispersal_probability.Count() - 1; Triplet myTriplet = cumulative_dispersal_probability[probIndex]; double cumProb = myTriplet.Prob; Pair locationPair = new Pair(myTriplet.Dir, myTriplet.Distance); disperseList.Add(locationPair); randIndex++; } else { double randValRound = Math.Floor(randValue * 1000) / 1000; if (randValRound > 0) { if (cum_prob_benchmarks.ContainsKey(randValRound)) { tempProbIndex = cum_prob_benchmarks[randValRound]; } else { randValRound = randValRound - 0.001; if (cum_prob_benchmarks.ContainsKey(randValRound)) { tempProbIndex = cum_prob_benchmarks[randValRound]; } } if (randValue > 0.997) { if (randValue > 0.999997) { double randValRoundTail2 = Math.Floor(randValue * 100000000) / 100000000; if (randValRoundTail2 > 0.99999999) { tempProbIndex = cum_prob_benchmarks_tail2[cum_prob_benchmarks_tail2.Keys.Max()]; } else { if (cum_prob_benchmarks_tail2.ContainsKey(randValRoundTail2)) { tempProbIndex = cum_prob_benchmarks_tail2[randValRoundTail2]; } else { randValRoundTail2 = randValRoundTail2 - 0.00000001; if (cum_prob_benchmarks_tail2.ContainsKey(randValRoundTail2)) { tempProbIndex = cum_prob_benchmarks_tail2[randValRoundTail2]; } } } } else { double randValRoundTail = Math.Floor(randValue * 1000000) / 1000000; if (randValRoundTail > 0.997) { tempProbIndex = cum_prob_benchmarks_tail[cum_prob_benchmarks_tail.Keys.Max()]; } else { if (cum_prob_benchmarks_tail.ContainsKey(randValRoundTail)) { tempProbIndex = cum_prob_benchmarks_tail[randValRoundTail]; } else { randValRoundTail = randValRoundTail - 0.000001; if (cum_prob_benchmarks_tail.ContainsKey(randValRoundTail)) { tempProbIndex = cum_prob_benchmarks_tail[randValRoundTail]; } } } } } if (tempProbIndex > probIndex) { probIndex = tempProbIndex; } } while (probIndex < cumulative_dispersal_probability.Count()) { Triplet myTriplet = cumulative_dispersal_probability[probIndex]; double cumProb = myTriplet.Prob; if (cumProb > randValue) { Pair locationPair = new Pair(myTriplet.Dir, myTriplet.Distance); disperseList.Add(locationPair); randIndex++; break; } probIndex++; } } } //s1.Stop(); //Console.WriteLine("Time to search " + randList.Count() + " probability:" + ((double)(s1.Elapsed.TotalSeconds)).ToString("0.0000 s")); //Console.WriteLine(); /*foreach (Triplet myTriplet in cumulative_dispersal_probability) * { * double cumProb = myTriplet.Prob; * if (cumProb > randList[randIndex]) * { * Pair locationPair = new Pair(myTriplet.Dir, myTriplet.Distance); * disperseList.Add(locationPair); * randIndex++; * if (randIndex == randList.Count) * break; * } * }*/ foreach (Pair locationPair in disperseList) { double dir = locationPair.First; double distance = locationPair.Second; double dj = Math.Cos(dir) * distance; // distance in x-direction (m) double dk = Math.Sin(dir) * distance; // distance in y-direction (m) int j = (int)Math.Round(dj / PlugIn.ModelCore.CellLength); // distance in x-direction (cells) int k = (int)Math.Round(dk / PlugIn.ModelCore.CellLength); // distance in y-direction (cells) int target_x = site.Location.Column + j; int target_y = site.Location.Row + k; bool leftMap = false; // Does dispersal leave the map (wrap)? // wrapLDD causes dispersers to stay within the landscape by wrapping the dispersal vector around the landscape (i.e., torus) if (wrapLDD) { int landscapeRows = PlugIn.ModelCore.Landscape.Rows; int landscapeCols = PlugIn.ModelCore.Landscape.Columns; if (target_x < 0 || target_y < 0 || target_x > landscapeCols || target_y > landscapeRows) { leftMap = true; // Dispersal goes off the map and wraps } //remainRow=SIGN(C4)*MOD(ABS(C4),$B$1) int remainRow = Math.Sign(k) * (Math.Abs(k) % landscapeRows); int remainCol = Math.Sign(j) * (Math.Abs(j) % landscapeCols); //tempY=A4+H4 int tempY = site.Location.Row + remainRow; int tempX = site.Location.Column + remainCol; //source_y=IF(J4<1,$B$1+J4,IF(J4>$B$1,MOD(J4,$B$1),J4)) if (tempY < 1) { target_y = landscapeRows + tempY; } else { if (tempY > landscapeRows) { target_y = tempY % landscapeRows; } else { target_y = tempY; } } if (tempX < 1) { target_x = landscapeCols + tempX; } else { if (tempX > landscapeCols) { target_x = tempX % landscapeCols; } else { target_x = tempX; } } } RelativeLocation targetLocation = new RelativeLocation(target_y - site.Location.Row, target_x - site.Location.Column); Site targetSite = site.GetNeighbor(targetLocation); if (leftMap) { SiteVars.Dispersed[targetSite] = SiteVars.Dispersed[targetSite] + lddEdgeWrapReduction; } else { SiteVars.Dispersed[targetSite]++; } //SiteVars.Dispersed[targetSite] = SiteVars.Dispersed[targetSite] + 100; // Each moth carries 100 eggs } } }