I'm following along with this http://www.cs.berkeley.edu/~vazirani/algorithms/chap1.pdf (bottom of page 24). In the book the author describes Al Khwarizmi multiplication algorithm. Here is my implementation
static int RecMultiply(int x, int y)
{
if (y == 0)
return 0;
int z = RecMultiply(x, y / 2);
if (y % 2 == 0)
return 2 * z;
else
return x + 2 * z;
}
I've stepped through the code a couple times and I'm just not grokking it. Why does the bottom else add x to 2 * z? It seems to me that z is used both as a running total and as the "right column" number in the algorithm in the book. Can someone break this code down and explain it please?
Since Multiplication is simple repetitive addition, if y is pair, you can divide it by two, and multiply x by two. (so, 2*2 = 2+2. 2*3 = 2+2+2, 2*4 = 2+2+2+2 ....)
If y is odd, you can subtract 1, to get a y that is pair, and you need to add an x, (basically, 1*y).
Here's a breakdown:
RecMultiply(5,5) :
+- z = RecMultiply(5,2)
| return 5 + 2 * z (=20 +5 =25)
|
|
+-- RecMultiply(5,2) :
+- z = RecMultiply(5,1)
| return 2 * z (=10)
|
+-- RecMultiply(5,1) :
+- z = RecMultiply(5,0)
| return 5 + 0
|
+---RecMultiply(5,0) :
return 0
RecMultiply(5,4) :
+- z = RecMultiply(5,2)
| return 2 * z (=)
|
+-- RecMultiply(5,2) :
+- z = RecMultiply(5,1)
| return 2 * z (=10)
|
+-- RecMultiply(5,1) :
+- z = RecMultiply(5,0)
| return 5 + 0
|
+---RecMultiply(5,0) :
return 0
So, basically, after the recursive bit (that takes care of all the pair multiplications), you might need to add another y, which in the first case above, is 5 for the first call).
Note the special case of y=1, which means x*1 which obviously is 5 in our case. Same logic applies.
You might want to look at it like this, if it helps:
static int RecMultiply(int x, int y)
{
switch (y)
{
case 0:
return 0;
break;
case 1:
return x;
break;
default:
return (y%2 ==0) ? RecMultiply(x, y/2)
: x + RecMultiply(x, y/2);
break;
}
}
I think it denotes the +1 (or odd cases) in a more understandable manner.
It is quite simple.
Z is calculated by multiplying x and half of y.
If y was of even parity (if section) return 2*z = 2 * x * y/2 = x * y (which is original request)
If y was of odd parity (else section) return 2*z + x. Why do we add x??? That is because y/2 will be the same for even and following odd number. So Z would be the same. But, with this if section we are detecting if it's odd or even and in case of odd we add x once more to the result.
Related
I have an issue with one moving element on my webapp. There is a double yvalue which can be from -10 to 10. Then I have a double tope which can be from 0 to 500, which represents position from top of an absolute element.
Both values are relative to each other. So when y is increasing tope is decreasing. Problem is I cannot change initial y = -10 value, otherwise I would just make it from 1 to 20. So I made some manipulations:
double y = -10 to 10 // comes from function, increases, decreases randomly, but never jumps over numbers
double ynum = 25;
double divy = 250;
double tope = 500;
if(y<0)
{
y = y * -1; //Since y starts at -10, I convert it to 10
y = y + 10; // I add 10 to reverse, so 10+10 is 20, or 9+10 is 19 ...
tope = ynum * y; // 25x20 first initial tope value is 500px, then lets say 25x19.. dropping
}
else // at some point y reaches positive side and I need to decrease tope value further
{
tope = divy / y;
}
All of this works fine. y goes from -10 to 10 and tope goes from 500 to 0. Except when y reaches double values below zero -0.154.., -0.254.., 0.345 .. since division/multiplication from fractions are quite different.
I tried to force all fractions to be 1 or 0, but then the moving absolute element looses it's smoothness.
How could I solve this problem?
You want a linear function, that maps [-10, 10] to [500, 0], so
tope = a*y + b
substituting your conditions:
0 = 10a + b => b=-10a
500 = -10a + b
Plugin the first to the second:
500 = -10a + -10a => a = -500/20 = -25
b = -10a = 250
So you just need:
tope = -25y + 250
You can consider the steps required to take to the whole range of y to get to the target range of tope:
y : [10..-10]
tope: [0..500]
Subtract 10 to align the first value:
y - 10: [0..-20]
tope : [0..500]
Now scale to match the size of the last value:
500/20 = 25
(y - 10)*25: [0..-500]
tope : [0..500]
Finally negate:
-(y - 10)*25: [0..500]
tope : [0..500]
so
tope = -(y - 10)*25
This question might answer yours. You can map the ranges of values together.
This is copied from the accepted answer:
You can do it with an Extension Method (for decimal for example):
public static class ExtensionMethods
{
public static decimal Map (this decimal value, decimal fromSource, decimal
toSource, decimal fromTarget, decimal toTarget)
{
return (value - fromSource) / (toSource - fromSource) * (toTarget -
fromTarget) + fromTarget;
}
}
Then you can use it like:
decimal res = 2.Map(1, 3, 0, 10);
// res will be 5
Type double is signed.
Equation for a straight line is y = m*x + c where m is the gradient and c is constant.
Given your end points A:(500,-10) and B:(0,+10)
Plug the coordinates of B into the equation: 10 = m*0 + c
Solve: c = 10
Plug in A and c: -10 = m*500 + 10
Solve: m = -1/25 = -0.04
Formulae (that work for positive and negative x and y)...
y = f(x) = -0.04*x + 10; // y from x
x = f(y) = 25*(10-y); // x from y
Depending on which position my agent is, along with its rotation, I need to determine the distances to a wall. As this function takes a little bit and needs to be called a lot, my idea was to store the distances by discretizing the position x and y as well as the angle.
My function is therefore called as follows:
float GetWallDistance(int x, int y, int angle)
{
return CalcWallDistance(x, y, angle);
}
where the x and y range from 0 to 500, and the angle ranges from 0 to 360. My first idea was to store it in a multidimensional array as follows:
Initialize the array somewhere by using float[,,] saveArray = new float[500, 500, 360];
float GetWallDistance(int x, int y, int angle)
{
float distance = 0;
if(saveArray[x, y, angle] == 0)
{
distance = CalcWallDistance(x, y, angle);
saveArray[x, y, angle] = distance;
}
else
{
distance = saveArray[x, y, angle];
}
return distance;
}
This tremendously sped up the calculation time but the problem here is that the saveArray takes up quite a big chuck of memory, and the agent will most likely not go through the entire 500 x 500 x 360 search space. A lot of memory is therefore taken up for nothing.
I therefore used a dictionary to store the data much more ram efficiently as follows:
Initialize the dictionary somewhere by using Dictionary<double, float> saveDictionairy = new Dictionary<double, float>();
float GetWallDistance(int x, int y, int angle)
{
double key = (double)x * 1000 + (double)y + (double)angle/1000
float distance = 0;
if(!saveDictionairy.TryGetValue(key, out distance))
{
distance = CalcWallDistance(x, y, angle);
saveDictionairy.Add(key, distance);
}
return distance;
}
(I tried using a string as key for the dictionary but it seemed that concatenating the x, y and angle takes up quite some time apparently)
This method is indeed a lot more memory efficient but the lookup time for the dictionary using the keys items increases by a large amount with respect to indexing the multi dimensional array.
Does anyone know a way how to store this data efficiently in a way that is also easy to lookup?
The .NET Dictionary uses a fast algorithm but has a fairly high overhead still. I experimented with making it faster a while ago. I found that I could make it 6x faster by deleting things that I did not need and by making other design changes.
For example, Dictionary uses the modulo operator to map from hash codes to buckets. % is surprisingly slow. It takes, I think, 31 CPU cycles. When I replaced that with hashCode & bucketCountMask where the bucket count is a power of two and bucketCountMask is buckets.Length - 1 I immediately realized a big performance gain.
I also deleted support for removing items and the iterator version feature. I directly exposed the slots array so that callers could directly mutate data in it.
This custom type was a lot faster because it was more specialized to my needs and it's API was a lot more difficult to use.
.NET Code on GitHub contains a DictionarySlim type for their internal use. Maybe you can use that.
From your current listed options, it seems the matrix approach is your best bet both in terms of performance and memory allocation.
I have run the following benchmarks:
[Benchmark(Baseline = true)]
public void MatrixTest()
{
// float[,,] saveArray = new float[501, 501, 361];
for (int x = 0; x <= 500; x++)
for (int y = 0; y <= 500; y++)
for (int angle = 0; angle <= 360; angle++)
if (saveArray[x, y, angle] == 0) saveArray[x, y, angle] = 42;
}
[Benchmark]
void IntKeyDictionaryTest()
{
// Dictionary<int, float> saveDictionary = new Dictionary<int, float>();
for (int x = 0; x <= 500; x++)
for (int y = 0; y <= 500; y++)
for (int angle = 0; angle <= 360; angle++)
{
int key = (x << 18) | (y << 9) | (angle);
if (!saveDictionary.TryGetValue(key, out float d)) saveDictionary[key] = 42;
}
}
[Benchmark]
void DoubleKeyDictionaryTest()
{
// Dictionary<double, float> saveDictionary = new Dictionary<double, float>();
for (int x = 0; x <= 500; x++)
for (int y = 0; y <= 500; y++)
for (int angle = 0; angle <= 360; angle++)
{
double key = (double)x * 1000 + (double)y + (double)angle / 1000l;
if (!saveDictionary.TryGetValue(key, out float d)) saveDictionary[key] = 42;
}
}
with following results:
Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |
------------------------ |------------:|----------:|----------:|------:|--------:|------------:|------------:|------------:|--------------------:|
MatrixTest | 727.9 ms | 5.733 ms | 5.363 ms | 1.00 | 0.00 | - | - | - | - |
IntKeyDictionaryTest | 4,682.1 ms | 12.017 ms | 11.241 ms | 6.43 | 0.05 | - | - | - | - |
DoubleKeyDictionaryTest | 12,804.1 ms | 66.425 ms | 62.134 ms | 17.59 | 0.17 | - | - | - | - |
So I managed to make a more efficient key for your dictionary knowing the fact that x, y and angle can each be represented on 9 bits => 27bits total which fits in an int.
Anyway from the looks of it, the matrix approach seems to be the winner.
I'd like to cycle a decimal digit by 1 using a single operation of possible.
if x is 0 - 8 then x = x + 1
if x is 9 then x = 0
or the opposite
if x is 1 - 9 then x = x - 1
if x is 0 then x = 9
Is there a way to do this with C# in one line of code? If not C# are there any other languages that could?
What if I wanted to cycle it by more than one (2 or 3 or whatever)?
I think what you're looking for is
var y = (x + 1) % 10;
This gives:
x y
------
0 1
1 2
...
8 9
9 0
To decrement
var y = (i + 9) % 10;
Obviously to change the amount, just change 1 or 9 respectively
int Cycle(int x)
{
return x+1 % 10;
}
int result = Cycle(0); // result is 1
int result = Cycle(8); // result is 9
int result = Cycle(9); // result is 0
int Cycle(int x, int by = 1)
{
return (x+by) % 10;
}
now you can call Cycle(9, 3) which should give you 2
The board is int[][] and I would like to find this shape
1
1
1
with all 4 of it's symmetric (rotational) variants from the board and log the positions.
e.g.
...
...
... x x x x x x ...
... x x 1 1 x x ...
... x 1 x x x x ...
... x x x x x x ...
...
...
Is it better to use F# to deal with these kinds of problems?
Below is my c# code for checking patterns vertically only (the code to check horizontally is simillar)
List<Position> GetMatchVertical(int reelID)
{
List<Position> ret = new List<Position>();
var myReel = board[reelID];
var leftReel = reelID - 1 >= 0 ? board[reelID - 1] : null;
var rightReel = reelID + 1 < boardSize ? board[reelID + 1] : null;
int currentColor = myReel[0];
for (int reelPosition = 1; reelPosition < boardSize; reelPosition++)
{
int nextColor = myReel[reelPosition];
if (currentColor == nextColor)
{
if (leftReel!=null)
{
if (reelPosition + 1 < boardSize && leftReel[reelPosition + 1] == currentColor)
{
ret.Add(logPosition(...));
}
}
if (rightReel!=null)
{
if (reelPosition - 2 >= 0 && rightReel[reelPosition - 2] == currentColor)
{
ret.Add(logPosition(...));
}
}
}
else
{
currentColor = nextColor;
}
}
return ret;
}
This is definitely a great fit for functional programming and F#. There is a large number of possible approaches. I think the solution by pad is probably the most direct one and it is a really good starting point. If you need something more general, then the solution by Huusom is quite nice.
There is even more general approach, which is to build a domain specific language (DSL) for detecting patterns in an array. This is more advanced functional technique, but it works really nicely for your example. If you did that, then you could express quite complex patterns in a really concise way. Here is an example:
// Create a detector that tests if a location
// contains 1 and returns 'false' when out of range
let one = border false (equals 1)
// A shape detector for your pattern
let pattern =
around (0, 0) one <&> around (1, 0) one <&>
around (-1, 1) one
// Test pattern with any rotation: Combine
// 4 possible rotations with logical or.
let any =
pattern <|> rotate pattern <|>
rotate (rotate pattern) <|>
rotate (rotate (rotate pattern))
This sample uses various primitives to build a declarative specification of the pattern. The value any represents a function that you can run to test whether the pattern occurs at a given location. It handles all rotations of the pattern and it also does bounds checks. You'd also need to add mirrored patterns, but that would be quite easy extension.
Explaining the implementation would probably need a full blog post, but here is a commented source code that should be quite readable:
/// A type that represents a function that tests
/// whether an array contains some pattern at a
/// specified location. It gets the location to
/// test & the array as arguments and returns bool.
type ShapeDetector = SD of (int -> int -> int[,] -> bool)
/// A primitive that tests whether the value at the
/// current location contains a value 'v'
let equals v = SD (fun x y arr -> arr.[x,y] = v)
/// A combinator that takes 'ShapeDetector' and
/// creates a new one that returns 'def' when
/// accessing outside of the array bounds
let border def (SD f) = SD (fun x y arr ->
if x < 0 || y < 0 || x >= arr.GetLength(0) || y >= arr.GetLength(1)
then def else f x y arr)
/// A combinator that calls a given ShapeDetector
/// at a location specified by offset dx, dy
let around (dx, dy) (SD f) = SD (fun x y arr ->
f (x + dx) (y + dy) arr)
/// A combinator that takes a ShapeDetector and
/// builds a new one, which is rotated by 90 degrees
let rotate (SD f) = SD (fun x y arr ->
f -y x arr)
/// Creates a shape detector that succeeds only
/// when both of the arguments succeed.
let (<&>) (SD f1) (SD f2) = SD (fun x y arr ->
f1 x y arr && f2 x y arr)
/// Creates a shape detector that succeeds
/// when either of the arguments succeed.
let (<|>) (SD f1) (SD f2) = SD (fun x y arr ->
f1 x y arr || f2 x y arr)
Finally, here is an example that runs the pattern detector on a sample 2D array:
// Create a 2D array as a sample input
let inp =
array2D [ [ 0; 0; 1 ]
[ 0; 1; 0 ]
[ 0; 1; 0 ] ]
// Get the underlying function and run it
// for all possible indices in the array
let (SD f) = any
for x in 0 .. 2 do
for y in 0 .. 2 do
printfn "%A %A" (x, y) (f x y inp)
You can find horizontal shapes using pattern matching in F# like this (do similarly for vertical shapes):
/// Try to match with horizontal shapes
/// 1 x x and 1 1 x
/// x 1 1 x x 1
///
/// 1 1 x and x x 1
/// x x 1 1 1 x
/// could be found by reversing matched sub-arrays
let matchHorizontalShapes (board: _ [] []) =
let positions = ResizeArray()
for i in 0..board.Length - 2 do
for j in 0..board.[0].Length - 3 do
match [|board.[i].[j..j+2];
board.[i+1].[j..j+2]|] with
| [|[|1; 1; _|];
[|_; 1; 1|]|] -> positions.Add((i, j), (i+1, j+1), (i+1, j+2))
positions.Add((i, j), (i, j+1), (i+1, j+2))
| [|[|1; _; _|];
[|_; 1; 1|]|] -> positions.Add((i, j), (i+1, j+1), (i+1, j+2))
| [|[|1; 1; _|];
[|_; _; 1|]|] -> positions.Add((i, j), (i, j+1), (i+1, j+2))
| _ -> ()
positions.ToArray()
If you create a set of coordinat offsets based on the pattern then you can get the values and match the result to a known set of values.
let find_matches board pattern =
let xb = Array2D.length1 board
let yb = Array2D.length2 board
// safe lookup on board
let get_value= function
| (x, _) when (x < 0) || (x >= xb) -> None
| (_, y) when (y < 0) || (y >= yb) -> None
| (x, y) -> Some (Array2D.get board x y)
// do a patten match on board.
let has_pattern = function
| [Some 1; Some 1; Some 1] -> true
| _ -> false
// se if a given coordinate is a match
let is_match (x,y) =
pattern
|> List.map (fun (x',y') -> (x+x', y+y')) // expand the coordinat to a list of coordinates
|> List.map get_value // find the values coordinates
|> has_pattern // match to pattern
[for x in 0..(xb-1) do for y in 0..(yb-1) -> x, y]
|> List.filter is_match
This functions works with a pattern of [(0,0); (1, -1); (1, -2)] (your example from above).
Please note I use an Array2D (int[,]) instead of int[][] given in your example.
I need to find all points that are on a line. I tried Bresenham's algorithm but it doesn't work on the following case:
(0, 0)
.-----------+-----------+-----------.
|...........| | |
|...........| | |
|.....XXXX..| | |
|........XXXX | |
|...........XXXXX | |
+-----------+---XXXX----+-----------+
| |......XXXXX|...........|
| |..........XXXX.........|
| |...........|.XXXXX.....|
| |...........|...........|
| |...........|...........|
`-----------+-----------+-----------ยด
(2, 1)
X is the actual line, . is what Bresenham's algorithm returns, notice the line crosses (1, 0) but it is not marked.
How can I find all the pixels a line goes through efficiently? I don't need this anti-aliased so I think Wu's algorithm is an overkill. The line endpoints are in middle of the pixels.
To reference the algorithm I have is:
int dx = System.Math.Abs(x0 - x1);
int dy = System.Math.Abs(y0 - y1);
int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;
int err = dx - dy;
int lx = x0;
int ly = y0;
for(int i = 0; true; i++)
{
Mark(x0, y0);
if(x0 == x1 && y0 == y1)
break;
int e2 = err * 2;
if(e2 > -dy)
{
err -= dy;
x0 += sx;
}
if(e2 < dx)
{
err += dx;
y0 += sy;
}
}
Well, just implement the obvious straightforward algorithm: start from one end of the line, find which side of the starting square it crosses, jump to the corresponding adjacent square... and so on. Walk until you reach the finish square.
The simplest way to implement it in integers would be to switch to superpixel precision: just multiply everything by a constant factor. The difficult part begins when you discover that you don't have enough integer range to multiply it sufficiently... I don't know whether this is the case in your case.