public int BothCycleDetectionAndFiniteLimit() { return (_viewPort.Resolution.GetPositionsRowFirst(). AsParallel(). Select(p => ScalarDoubleKernel.FindEscapeTime(_viewPort.GetComplex(p), MaxIterations).IsInfinite). Count()); }
public static void CalculateToCsv(string edgeSpansPath, int pointsToCalculate) { using var edgeSpans = EdgeSpanStream.Load(edgeSpansPath); using var timedOperation = TimedOperation.Start("edge spans", totalWork: pointsToCalculate > 0 ? pointsToCalculate : edgeSpans.Count); using var outputFile = File.OpenWrite(edgeSpansPath + $".{timedOperation.TotalWork}.borderPoints.csv"); using var textWriter = new StreamWriter(outputFile); using var csv = new CsvWriter(textWriter, CultureInfo.InvariantCulture); //var kernel = KernelBuilder.BuildScalarKernel(edgeSpans.ComputationType); var sequence = edgeSpans.Take((int)timedOperation.TotalWork). Select((logicalSpan, index) => new { LogicalSpan = logicalSpan, Index = index }). AsParallel(). Select(result => { var span = result.LogicalSpan.ToConcreteDouble(edgeSpans.ViewPort); var borderPoint = span.FindBoundaryPoint(Constant.IterationRange.Max); var escapeTime = ScalarDoubleKernel.FindEscapeTime(borderPoint, Constant.IterationRange.Max); timedOperation.AddWorkDone(1); return ( Index: result.Index, Location: result.LogicalSpan.Location, Span: span, Point: borderPoint, EscapeTime: escapeTime ); }); csv.WriteField("Index"); csv.WriteField("Location"); csv.WriteField("Span"); csv.WriteField("Border Point"); csv.WriteField("Escape Time"); csv.NextRecord(); foreach (var result in sequence) { csv.WriteField(result.Index); csv.WriteField(result.Location); csv.WriteField(result.Span); csv.WriteField(result.Point); csv.WriteField(result.EscapeTime); csv.NextRecord(); } }
public static void CalculateWithDoubles(string edgeSpansPath, int pointsToCalculate) { using var edgeSpans = EdgeSpanStream.Load(edgeSpansPath); using var timedOperation = TimedOperation.Start("edge spans", totalWork: pointsToCalculate > 0 ? pointsToCalculate : edgeSpans.Count); var points = edgeSpans.Take((int)timedOperation.TotalWork). AsParallel(). Select(span => span. ToConcreteDouble(edgeSpans.ViewPort). FindBoundaryPoint(Constant.IterationRange.Max)). Where(point => { var escapeTime = ScalarDoubleKernel.FindEscapeTime(point, Constant.IterationRange.Max); timedOperation.AddWorkDone(1); return(Constant.IterationRange.IsInside(escapeTime)); }); PointStream.Write(edgeSpansPath + $".{timedOperation.TotalWork}.doublePoints", edgeSpans.ViewPort, points); }
static Complex FindBorderPointMagnitudeSquared(EdgeSpan span, int iterationLimit) { // var initialLength2 = span.LengthSquared(); int maxSubdivisions = 38; //double oldLength = 0; //while (oldLength != initialLength2) //{ // maxSubdivisions++; // oldLength = initialLength2; // initialLength2 /= 2; //} //Console.WriteLine(maxSubdivisions); double lastLength = 0; for (int i = 0; i < maxSubdivisions; i++) { //var length = span.LengthSquared(); //if (length == lastLength) //{ // return span.NotInSet; //} //lastLength = length; var middle = span.GetMidPoint(); var escapeTime = ScalarDoubleKernel.FindEscapeTime(middle, iterationLimit); span = escapeTime.IsInfinite ? new EdgeSpan(middle, span.NotInSet) : new EdgeSpan(span.InSet, middle); //if (i % 10 == 0) //{ // Console.WriteLine(i); //} } return(span.NotInSet); }
public static void RenderSingleSpan(string edgeSpansPath, int spanIndex, int sideResolution) { var resolution = new Size(sideResolution, sideResolution); using var spans = EdgeSpanStream.Load(edgeSpansPath); using var timer = TimedOperation.Start("points", totalWork: resolution.Area()); var random = new Random(); var index = spanIndex >= 0 ? spanIndex : random.Next(0, spans.Count); var imageFilePath = Path.Combine( Path.GetDirectoryName(edgeSpansPath) ?? throw new Exception($"Could not get directory name: {edgeSpansPath}"), Path.GetFileNameWithoutExtension(edgeSpansPath) + $"_{index}_{sideResolution}x{sideResolution}.png"); Log.Info($"Using edge span index {index:N0}"); Log.Info($"Output file: {imageFilePath}"); var span = spans.ElementAt(index).ToConcreteDouble(spans.ViewPort); var spanLength = span.Length(); Log.Info($"Edge span: {span} (length: {spanLength})"); var image = new FastImage(resolution); var viewPort = new ViewPort(GetArea(span), resolution); Log.Info($"View port: {viewPort}"); var positionInSet = viewPort.GetPosition(span.InSet); var positionNotInSet = viewPort.GetPosition(span.NotInSet); var highlightPixelRadius = resolution.Width / 100; var borderPoint = span.FindBoundaryPoint(Constant.IterationRange.Max); Log.Info($"Border point: {borderPoint} (escape time: {ScalarDoubleKernel.FindEscapeTime(borderPoint)})"); var borderPointPosition = viewPort.GetPosition(borderPoint); // TODO: Why is the inner loop parallelized? for (int row = 0; row < resolution.Height; row++) { Parallel.For(0, resolution.Width, col => { var position = new Point(col, row); var c = viewPort.GetComplex(position); Color PickColor() { if (position.DistanceSquaredFrom(positionInSet) <= highlightPixelRadius) { return(Color.Red); } if (position.DistanceSquaredFrom(positionNotInSet) <= highlightPixelRadius) { return(Color.ForestGreen); } if (position.DistanceSquaredFrom(borderPointPosition) <= highlightPixelRadius) { return(Color.Fuchsia); } var isInSet = ScalarDoubleKernel.FindEscapeTime(c, Constant.IterationRange.Max).IsInfinite; return(isInSet ? Color.FromArgb(0x20, 0x20, 0x20) : Color.White); } image.SetPixel(position, PickColor()); }); timer.AddWorkDone(resolution.Width); } image.Save(imageFilePath); }