Ulam's Spiral (Prime Number Spiral) - c#

I'm looking for ideas/code (preferably C#, but other languages work too) to create Ulam's Spiral infinitely large (limited by length of time the program is running, or until stopped).
Now the numbers are all primes so the code for those is rather irrelevant. The interesting part is how to code the arrangement in the evergrowing (infinite) spiral, what kind of data structure is good to support it, and maybe ideas for output (graphics file, text file?).
How would you go about this?

Consider the lengths of each side:
1, 1, 2, 2, 3, 3, 4, 4, ...
The straightforward thing is to iterate over each side, rendering that side.
You can use LOGO style rendering primitives:
Angle = 0;
x=0; y = 0;
int number = 1;
int sideLength = 1;
StartLine();
for (int side = 1; side < maxSize; side++) {
for (int k = 0; k < sideLength; k++) {
Forward(1);
number++;
if (isPrime(number)) {
StopLine();
Ouput(number);
StartLine();
}
}
TurnLeft();
if (side % 2 == 0) sideLength++;
}
You might improve this by only iterating over primes on a side:

The following program works by directly calculating the coordinates of a number. The method NumberToPoint() performs the following mapping.
0 => (x0 , y0 )
1 => (x0 + 1, y0 )
2 => (x0 + 1, y0 - 1)
3 => (x0 , y0 - 1)
4 => (x0 - 1, y0 - 1)
5 => (x0 - 1, y0 )
6 => ...
The rest is a very simple prime number test and a small console application.
In order to save an image I would consider two solutions. If you can create a buffer for the whole image, you can just use the program below to fill the buffer.
If the buffer would be to large, I would create a method PointToNumber() and invert the calculation - the method takes two coordinates and returns the number at this point. With this method you can iterate from top to bottom and left to right and calculate the number at this point, check if it is prime, and output the pixel as you go without a buffer. But for both solutions the image size should be be known before you start, because adding pixels at the top and left is quite expensive (but of cause possible).
Questions
Any good ideas for converting the coefficient lookup in NumberToPoint() into rock solid math without using modulo, integer division, and sign a thousand times?
Any good ideas to shorten or speed up the prime number test?
Code
using System;
using System.Drawing;
using System.Linq;
using System.Threading;
namespace UlamsSpiral
{
public static class Program
{
public static void Main()
{
Int32 width = 60;
Int32 height = 60;
Console.SetWindowSize(Math.Min(width, 120), Math.Min(height, 60));
Console.SetBufferSize(width, height);
Console.CursorVisible = false;
Int32 limit = (Int32)Math.Pow(Math.Min(width, height) - 2, 2);
for (Int32 n = 1; n <= limit; n++)
{
Point point = NumberToPoint(n - 1, width / 2 - 1, height / 2);
Console.ForegroundColor = n.IsPrime() ? ConsoleColor.DarkBlue : ConsoleColor.DarkGray;
Console.SetCursorPosition(point.X, point.Y);
Console.Write('\u25A0');
Console.SetCursorPosition(0, 0);
Console.Write(n);
Thread.Sleep(10);
}
Console.ReadLine();
}
private static Point NumberToPoint(Int32 n, Int32 x0, Int32 y0)
{
Int32[,] c = { { -1, 0, 0, -1, 1, 0 }, { -1, 1, 1, 1, 0, 0 }, { 1, 0, 1, 1, -1, -1 }, { 1, -1, 0, -1, 0, -1 } };
Int32 square = (Int32)Math.Floor(Math.Sqrt(n / 4));
Int32 index;
Int32 side = (Int32)Math.DivRem(n - 4 * square * square, 2 * square + 1, out index);
Int32 x = c[side, 0] * square + c[side, 1] * index + c[side, 2];
Int32 y = c[side, 3] * square + c[side, 4] * index + c[side, 5];
return new Point(x + x0, y + y0);
}
private static Boolean IsPrime(this Int32 n)
{
if (n < 3) return (n == 2);
return Enumerable.Range(2, (Int32)Math.Sqrt(n)).All(m => n % m != 0);
}
}
}

One possible way to do it is to create a linear array or a List to store the numbers and use a formula to determine when the direction needs to change.
As for output, I liked the example on wikipedia of drawing a black pixel for a prime and a white pixel for all other numbers.

Why not have a "generator" process/thread that creates the numbers and a "reader/display" process/thread that displays them, then you can separate the creation from the display and then the program will only really be limited by how much data the "reader/display" consumes. Since i would assume the "generator" needs a fairly constant sized set of data to work with.

Related

Matrix transformation, rotation around x axis

I'm struggling my way through The Ray Tracer Challenge and have come to a test case in chapter 4 that I'm not able to get past.
Scenario: Rotating a point around the x axis
Given p ← point(0, 1, 0)
And half_quarter ← rotation_x(π / 4)
And full_quarter ← rotation_x(π / 2)
Then half_quarter * p = point(0, √2/2, √2/2)
And full_quarter * p = point(0, 0, 1)
The first assert (half_quarter) works as expected, but the second (full_quarter) fails.
Expected Matrix.Multiply(full_quarter, p) to be equal to (0, 0, 1, 1), but found (0, 6.12323399573677E-17, 1, 1).'
My implementation of rotation_x is as follows:
public static double[,] rotation_x(double radians)
{
var cos = Math.Cos(radians);
var sin = Math.Sin(radians);
return new[,]
{
{ 1, 0, 0, 0 },
{ 0, cos, -sin, 0 },
{ 0, sin, cos, 0 },
{ 0, 0, 0, 1 }
});
}
Here's my multiplication method:
public static double[] Multiply(double[,] a, (double x, double y, double z, double w) b)
{
var product = new double[4];
for (var r = 0; r < 4; r++)
{
product[r] = a[r, 0] * b.x
+ a[r, 1] * b.y
+ a[r, 2] * b.z
+ a[r, 3] * b.w
;
}
return product;
}
I have a lot of tests cases for matrices and vector multiplication from earlier chapters, so I'm pretty sure that part works as it should. But what else could be wrong?
You are passing in some value for π, but Math.PI is not exactly equal to π. It's approximately equal to π to within about 17 significant digits.
The sine of exactly π is exactly zero. The sine of something very close to π is very close to zero. Which is what you got: 6 x 10-17 is pretty close to zero.
Similarly, the cosine of π/2 is exactly zero, but the value of π/2 you are passing in is only accurate to 17 digits, so the result is only accurate to 17 digits.
Similarly, Sqrt(2.0)/2.0 is not exactly √2/2. It's an approximation accurate to about 17 decimal places.
Every number in your system that is not an integer is correct to only within 17 decimal places, so there's no mystery here; your results are correct to within 17 decimal places because your inputs are correct to within 17 decimal places. You only get out as much precision as you put in. Doubles are not infinite-precision!
(Nice use of tuple types, by the way -- but consider making structs to represent some of these concepts; that way you can put the methods associated with those concepts in the struct.)

Iterating over an uneven set of numbers

I have a set of numbers in the form of { -1, 0, +1 } which I have to iterate over using two loops, much like you would when using a 2D array.
The whole set then becomes every combination of the numbers above:
{ -1, -1 } -> { +1, +1 }, which is 9 in total.
However, the set { 0, 0 } I have to skip. Normally I would just check with an if statement, but using this inside two nested loops will make it check for this condition on every run.
Is there an efficient way to somehow do this?
UPDATE: I feel this deserves a little more detail, because there might be a completely different solution this problem than what I want to do above.
It is basicly to check adjacent cells within an array. So { 0, 0 } is cell we are checking, but I wish to check every cell adjacent to it, not including the main cell.
Imagine we had a 2D array int[,] array = new int[,] { ... };
If we then access the array at any index approximately in the middle of it (not close to any edge index; like the bottom/top row or bottom/top column), our conceptual bird's eye view of the array would look like this:
[-1, -1] [-1, 0] [-1, +1]
[0, -1] [0, 0] [0, +1]
[+1, -1] [+1, 0] [+1, +1]
[0,0] is our current element. We can access every adjacent element/cell using the above numbers for [row,column].
A typical loop to do this would look like this:
for (int i = row-1; i <= row+1; ++i) {
for (int j = col-1; j <= col+1; ++j) {
if (i == row && j == col) continue;
...
}
}
Can we avoid the if statement?
After your edit, it seems you don't need loops at all and your desired result has 8 well defined elements.
So you coud simply create a little method that gives you all adjacent cells to your main cell:
Point[] GetAdjacentPoints(Point p)
{
return new[]{
new Point { X = p.X - 1, Y = p.Y - 1 },
new Point { X = p.X, Y = p.Y - 1 },
new Point { X = p.X + 1, Y = p.Y - 1 },
new Point { X = p.X - 1, Y = p.Y },
// leave out p itself
new Point { X = p.X + 1, Y = p.Y },
new Point { X = p.X - 1, Y = p.Y + 1},
new Point { X = p.X, Y = p.Y + 1},
new Point { X = p.X + 1, Y = p.Y + 1}
};
}
(I assume Point to be something like struct Point {public int X {get;set;} public int Y {get;set;}} or any other type to hold two integers).
You can use this method like this:
foreach(Point adjacent in GetAdjacentPoints(new Point {X = 0, Y = 0})
Console.WriteLine($"X: {adjacent.X} Y: {adjacent.Y}");
Output:
X: -1 Y: -1
X: 0 Y: -1
X: 1 Y: -1
X: -1 Y: 0
X: 1 Y: 0
X: -1 Y: 1
X: 0 Y: 1
X: 1 Y: 1
Just compute every single pair and then remove the one pair you want to exclude from your final set. [well implemented] Sets are specifically designed for efficient removal (more efficient than linear anyway, O(1) for hash based sets, O(log(n)) for tree based sets), so that will be faster than checking every single value in the set, which is what you would be doing by having the check in your loop.
I suggest you measure it first and see if this is really a problem, because depending on the type of collection you're using, the Add operation may be more costly than the if statement (in my case below, it consists of creating a new list and then adding that list to another list).
For example, using a List<int> to hold the original set, and a List<List<int>> to hold the combinations, I find that using the if statement is faster than not using it (and if we don't use it then we still need to iterate over the pairs to find the ones we want to remove).
Below is the test I ran, using loops with the if and without the if, with 2001 items in the set (from -1000 to 1000), which creates a total of 4004000 sets. I ran the tests in a loop 100 times and displayed the average time in an attempt to get the most accurate result:
private static void Main()
{
var items = Enumerable.Range(-1000, 2001).ToList();
var combinations = new List<List<int>>();
var withIfCount = new List<long>();
var withoutIfCount = new List<long>();
var sw = new Stopwatch();
// Both test are run 100 times
for (int count = 0; count < 100; count++)
{
sw.Restart();
for (int outer = 0; outer < items.Count; outer++)
{
for (int inner = 0; inner < items.Count; inner++)
{
if (outer == 0 && inner == 0) continue;
combinations.Add(new List<int> {outer, inner});
}
}
sw.Stop();
withIfCount.Add(sw.ElapsedMilliseconds);
combinations.Clear();
sw.Restart();
for (int outer = 0; outer < items.Count; outer++)
{
for (int inner = 0; inner < items.Count; inner++)
{
combinations.Add(new List<int> {outer, inner});
}
}
sw.Stop();
withoutIfCount.Add(sw.ElapsedMilliseconds);
combinations.Clear();
}
// Display averages
Console.WriteLine("Average time with 'if': " + withIfCount.Average());
Console.WriteLine("Average time without 'if': " + withoutIfCount.Average());
Console.WriteLine("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output

Connected-component labeling algorithm optimization

I need some help with optimisation of my CCL algorithm implementation. I use it to detect black areas on the image. On a 2000x2000 it takes 11 seconds, which is pretty much. I need to reduce the running time to the lowest value possible to achieve. Also, I would be glad to know if there is any other algorithm out there which allows you to do the same thing, but faster than this one. So here is my code:
//The method returns a dictionary, where the key is the label
//and the list contains all the pixels with that label
public Dictionary<short, LinkedList<Point>> ProcessCCL()
{
Color backgroundColor = this.image.Palette.Entries[1];
//Matrix to store pixels' labels
short[,] labels = new short[this.image.Width, this.image.Height];
//I particulary don't like how I store the label equality table
//But I don't know how else can I store it
//I use LinkedList to add and remove items faster
Dictionary<short, LinkedList<short>> equalityTable = new Dictionary<short, LinkedList<short>>();
//Current label
short currentKey = 1;
for (int x = 1; x < this.bitmap.Width; x++)
{
for (int y = 1; y < this.bitmap.Height; y++)
{
if (!GetPixelColor(x, y).Equals(backgroundColor))
{
//Minumum label of the neighbours' labels
short label = Math.Min(labels[x - 1, y], labels[x, y - 1]);
//If there are no neighbours
if (label == 0)
{
//Create a new unique label
labels[x, y] = currentKey;
equalityTable.Add(currentKey, new LinkedList<short>());
equalityTable[currentKey].AddFirst(currentKey);
currentKey++;
}
else
{
labels[x, y] = label;
short west = labels[x - 1, y], north = labels[x, y - 1];
//A little trick:
//Because of those "ifs" the lowest label value
//will always be the first in the list
//but I'm afraid that because of them
//the running time also increases
if (!equalityTable[label].Contains(west))
if (west < equalityTable[label].First.Value)
equalityTable[label].AddFirst(west);
if (!equalityTable[label].Contains(north))
if (north < equalityTable[label].First.Value)
equalityTable[label].AddFirst(north);
}
}
}
}
//This dictionary will be returned as the result
//I'm not proud of using dictionary here too, I guess there
//is a better way to store the result
Dictionary<short, LinkedList<Point>> result = new Dictionary<short, LinkedList<Point>>();
//I define the variable outside the loops in order
//to reuse the memory address
short cellValue;
for (int x = 0; x < this.bitmap.Width; x++)
{
for (int y = 0; y < this.bitmap.Height; y++)
{
cellValue = labels[x, y];
//If the pixel is not a background
if (cellValue != 0)
{
//Take the minimum value from the label equality table
short value = equalityTable[cellValue].First.Value;
//I'd like to get rid of these lines
if (!result.ContainsKey(value))
result.Add(value, new LinkedList<Point>());
result[value].AddLast(new Point(x, y));
}
}
}
return result;
}
Thanks in advance!
You could split your picture in multiple sub-pictures and process them in parallel and then merge the results.
1 pass: 4 tasks, each processing a 1000x1000 sub-picture
2 pass: 2 tasks, each processing 2 of the sub-pictures from pass 1
3 pass: 1 task, processing the result of pass 2
For C# I recommend the Task Parallel Library (TPL), which allows to easily define tasks depending and waiting for each other. Following code project articel gives you a basic introduction into the TPL: The Basics of Task Parallelism via C#.
I would process one scan line at a time, keeping track of the beginning and end of each run of black pixels.
Then I would, on each scan line, compare it to the runs on the previous line. If there is a run on the current line that does not overlap a run on the previous line, it represents a new blob. If there is a run on the previous line that overlaps a run on the current line, it gets the same blob label as the previous. etc. etc. You get the idea.
I would try not to use dictionaries and such.
In my experience, randomly halting the program shows that those things may make programming incrementally easier, but they can exact a serious performance cost due to new-ing.
The problem is about GetPixelColor(x, y), it take very long time to access image data.
Set/GetPixel function are terribly slow in C#, so if you need to use them a lot, you should use Bitmap.lockBits instead.
private void ProcessUsingLockbits(Bitmap ProcessedBitmap)
{
BitmapData bitmapData = ProcessedBitmap.LockBits(new Rectangle(0, 0, ProcessedBitmap.Width, ProcessedBitmap.Height), ImageLockMode.ReadWrite, ProcessedBitmap.PixelFormat);
int BytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(ProcessedBitmap.PixelFormat) / 8;
int ByteCount = bitmapData.Stride * ProcessedBitmap.Height;
byte[] Pixels = new byte[ByteCount];
IntPtr PtrFirstPixel = bitmapData.Scan0;
Marshal.Copy(PtrFirstPixel, Pixels, 0, Pixels.Length);
int HeightInPixels = bitmapData.Height;
int WidthInBytes = bitmapData.Width * BytesPerPixel;
for (int y = 0; y < HeightInPixels; y++)
{
int CurrentLine = y * bitmapData.Stride;
for (int x = 0; x < WidthInBytes; x = x + BytesPerPixel)
{
int OldBlue = Pixels[CurrentLine + x];
int OldGreen = Pixels[CurrentLine + x + 1];
int OldRed = Pixels[CurrentLine + x + 2];
// Transform blue and clip to 255:
Pixels[CurrentLine + x] = (byte)((OldBlue + BlueMagnitudeToAdd > 255) ? 255 : OldBlue + BlueMagnitudeToAdd);
// Transform green and clip to 255:
Pixels[CurrentLine + x + 1] = (byte)((OldGreen + GreenMagnitudeToAdd > 255) ? 255 : OldGreen + GreenMagnitudeToAdd);
// Transform red and clip to 255:
Pixels[CurrentLine + x + 2] = (byte)((OldRed + RedMagnitudeToAdd > 255) ? 255 : OldRed + RedMagnitudeToAdd);
}
}
// Copy modified bytes back:
Marshal.Copy(Pixels, 0, PtrFirstPixel, Pixels.Length);
ProcessedBitmap.UnlockBits(bitmapData);
}
Here is the basic code to access pixel data.
And I made a function to transform this into a 2D matrix, it's easier to manipulate (but little slower)
private void bitmap_to_matrix()
{
unsafe
{
bitmapData = ProcessedBitmap.LockBits(new Rectangle(0, 0, ProcessedBitmap.Width, ProcessedBitmap.Height), ImageLockMode.ReadWrite, ProcessedBitmap.PixelFormat);
int BytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(ProcessedBitmap.PixelFormat) / 8;
int HeightInPixels = ProcessedBitmap.Height;
int WidthInPixels = ProcessedBitmap.Width;
int WidthInBytes = ProcessedBitmap.Width * BytesPerPixel;
byte* PtrFirstPixel = (byte*)bitmapData.Scan0;
Parallel.For(0, HeightInPixels, y =>
{
byte* CurrentLine = PtrFirstPixel + (y * bitmapData.Stride);
for (int x = 0; x < WidthInBytes; x = x + BytesPerPixel)
{
// Conversion in grey level
double rst = CurrentLine[x] * 0.0721 + CurrentLine[x + 1] * 0.7154 + CurrentLine[x + 2] * 0.2125;
// Fill the grey matix
TG[x / 3, y] = (int)rst;
}
});
}
}
And the website where the code comes
"High performance SystemDrawingBitmap"
Thanks to the author for his really good job !
Hope this will help !

C#: Seeking fast datastructure to add pixels to a partitioned HSB histogram

In my application I read RGB pixel values from several images using fast unmanaged code and then convert them to HSB colors. Now I'd like to build an HSB histogram using the following partitions:
Hue: 18 partitions, resulting in intervals of 20 from 0...360
Saturation: 3 partitions, resulting in intervals of 0,33 from 0...1
Brightness: 3 partitions, resulting in intervals of 0,33 from 0...1
So my histogram has a total of 18*3*3=162 partitions (bins) which consist of the lower interval borders for each channel:
Bin1: [0, 0, 0]
Bin2: [0, 0, 0.33]
Bin3: [0, 0, 0.66]
Bin4: [0, 0.33, 0]
Bin5: [0, 0.33, 0.33]
...
Bin162: [340, 0.66, 0.66]
I implemented this pretending that each bin would be an HSB color itself. So I calculated the bin interval borders, created HsbColor instances from those values and put the colors (wrapped in the HsbHistogramBin class) in a simple list.
When adding a new HsbColor to my histogram, I use the following code to determine which bin I need to increment:
private HsbHistogramBin FindBin(HsbColor color)
{
HsbHistogramBin bin = null;
bool foundBin = false;
for (int i = Bins.Count - 1; i >= 0; i--)
{
bin = Bins[i];
if (bin.Color.Hue > color.Hue)
continue;
if (bin.Color.Saturation > color.Saturation)
continue;
if (bin.Color.Brightness > color.Brightness)
continue;
foundBin = true;
break;
}
return foundBin ? bin : null;
}
public void AddColor(HsbColor color)
{
FindBin(color).Value++;
}
Obviously this is way too slow. In a worst-case scenario, each pixel needs 162 iterations to find its bin which results in at least millions of iterations for one single image.
My question is: How can I speed this data structure up so that I can immediately find the right bin for my pixels? A simple array with the length of 162 might work but how do I calculate the right bin index for a given pixel that isn't yet reduced to the mentioned partitions and might contain values like [259.234, 0.5634, 0.90534]?
Why not just simply use a 3 dimensional array? Like so:
int[,,] histogram = new int[18, 3, 3];
// initialize to 0
for(int h = 0; h < 18; h++) {
for(int s = 0; s < 3; s++) {
for(int b = 0; b < 3; b++) {
histogram[h, s, b] = 0;
}
}
}
// foreach pixel...
HsbColor c = ... // color of pixel
int h = (int)(c.Hue / 20);
int s = (int)(c.Saturation * 3);
int b = (int)(c.Brighthess * 3);
// take care of boundary cases (Hue, Saturation or Brightness maxed out)
if(h >= 18) h = 17;
if(s >= 3) s = 2;
if(b >= 3) b = 2;
histogram[h, s, b]++;
NB: I'm assuming here that your total pixel count (more precisely, the maximum number of pixels that will fall into 1 bin) will not exceed int.MaxValue. Otherwise, consider using long datatype for the histogram instead of int.
You can convert your HSV number into one unsigned long like so:
ulong colorLookupValue = (color.Hue/18) * 9 + (ulong)((color.Saturation*3) * 3) + (ulong)(color.Brightness * 3)
This is your bin index.

perfect side combination of right triangle

I want to get a list of: Sides of Right Triangle
which are perfectly whole numbers.(where each sides less than 100)
Example:
//I want these combination to be printed
3, 4, 5
6, 8, 10 |'.
5, 12, 13 12 | '. 13 (Figure is just Example)
. | '.
. |______'.
. 5
// I don't want these
1, 1, 1.414.... |'.
. 1 | '. √ˉ2 = 1.414.... (Figure is just Example)
. | '.
|______'.
1
Update:
I do like this: But this is very heavy code(regarding optimization)
for(int i=1;i<100;i++)
{
for(int j=1;j<100;j++)
{
for(int k=1;k<100;k++)
{
if(i*i + j*j == k*k)
{
//print i, j, k
}
}
}
}
What you're looking for are the Pythagorean triples.
// Obvious min is 1, obvious max is 99.
for(int i = 1; i != 100; ++i)
{
// There's no point going beyond the lowest number that gives an answer higher than 100
int max = 100 * 100 - i * i;
// There's no point starting lower than our current first side, or we'll repeat results we already found.
for(int j = i; j * j <= max; ++j)
{
// Find the square of the hypotenuse
int sqr = i * i + j * j;
// We could have a double and do hyp == Math.Round(hyp), but lets avoid rounding error-based false positives.
int hyp = (int)Math.Sqrt(sqr);
if(hyp * hyp == sqr)
{
Console.WriteLine(i + ", " + j + ", " + hyp);
// If we want to e.g. have not just "3, 4, 5" but also "4, 3, 5", then
// we can also here do
// Console.WriteLine(j + ", " + i + ", " + hyp);
}
}
}
I've used this formula in C# for generating Pythagorean triples in the past. But there are many other options on that page.
You can improve your code by removing the innermost loop if you take advantage of the fact that for each pair of catheti, there is only one possible value for the hypotenuse. Instead of looping around to find that value, you can compute it using the Pythagorean theorem and test if it is an whole number.
Something like:
// compute the hypotenuse
var hypotenuse = Math.Sqrt(i*i + j*j);
// test if the hypotenuse is a whole number < 100
if(hypotenuse < 100 && hypotenuse == (int)hypotenuse)
{
// here's one!
}
Some other improvements you can do include:
Once you've checked a pair of catheti (x,y), don't check for (y,x) again;
Once you find a triangle (x,y,z), you can include all triangles with the same sides multiplied by a constant factor (k*x, k*y, k*z), i.e, if you find (3,4,5) you can include (6,8,10), (9,12,15), (12,16,20), etc (this one might be a too much effort for little gains);
A fairly good exhaustive search:
for(i=1;i<100;i++) {
k=i;
for(j=1;k<100;j++) {
while(i*i+j*j<k*k) {
k++;
}
if(i*i+j*j==k*k) {
printf("%d %d %d", i, j, k);
}
}
}
In a declarative language (Mathematica):
FindInstance[x^2 + y^2==z^2 &&1<=z<=100 && 1<=y<=x<=100, {x, y, z}, Integers,100]

Categories