remove ILArray<> elements - c#

Using ILNumerics, I am trying to take the first n number of columns of an ILArray<> in the most efficient way possible.
using(ILScope.Enter(inframe)
{
ILArray<complex> frame = ILMath.check(inframe);
int[] dims = frame.Size.ToIntArray(); //frame is a 2d ILArray
frame.SetRange(complex.Zero, dims[0] -1 , (dims[1] * 2 - 1)); //doubles the size of the array with zeros.
//TODO- various computations.
frame.SetRange(null, dims[0], dims[1] - 1); //EXCEPTION: why doesn't this work?
}
In this example I am trying to take only the first half of the frame, but I am unable to size it back to the original dimensions. I have tried various permutations based on http://ilnumerics.net/ArrayAlter.html but have been unsuccessful.

The documentation for shrinking of ILNumerics arrays says:
The range definition must address the full dimension - for all dimensions except the one, which is to be removed.
You want to remove the last half from the 2nd dimension. So you must define full ranges for all other dimensions involved. Here, since frame is a matrix, there are only 2 dimensions. Hence, the first must get fully addressed.
It should work easier by using the C# indexer. The following example assumes your code in a class derived from ILMath. Otherwise, add ILMath. before all the full, r, and end functions / properties:
A[full, r(end / 2, end)] = null;
Watch out for ‘off by one’ errors and addressing with ‘end’. You may want to use end / 2 + 1 instead ?
Since you want the most efficient way, performance seems to be important to you. In this case, you should try to prevent from expanding and shrinking arrays! It is better to work with two arrays of different sizes: a large one and the original one. Copy the data accordingly. Expanding and shrinking does copy the data anyway, so this is not a disadvantage. Furthermore, frame.Size.ToIntArray() is not needed here. Simply use frame.S[0]and frame.S[1] for the length of the dimensions 0 and 1.

Related

What algorithm to use to check if one set overlaps to another?

I have many sets of integers. I need to check if one overlaps (at least one same element exists in both sets) to another. What is the best way to do it. I compared two ways:
HashSet<int> hs1, hs2;
hs1.Overlaps(hs2);
and
SortedSet<int> ss1, ss2;
ss1.Overlaps(ss2);
HashSet is beter because in both cases overlaps gets enumerable, and do scan in enumerable and lookup in set.
But I feel that beter algorithm exists to check overlaping in sorted sets.
Does anyone know algorithm which allows to quick check overlaping using the fact that both sets is sorted?
UPD1
The size of each set is about 100-1000 well distributed integers.
It is not possible to do better than O(min(size of the first set, size of the second set)), because you cannot tell if two sets intersect without looking through all elements of at least one of them in the worst case.
This depends quite a lot on the size of the problem (may be a few hundred to a few trillion entries per set) and the way the input is presented (files ? fits into memory ? on multiple machines).
In general, with pure comparisons, we can't find all overlapping sets better than O(n * log(n)) where 'n' is the total number of elements since duplicate detection (proven to be Omega(n * log (n)) can be reduced to this problem. There are a few other heuristics that can be used depending on the size of the problem and data sets if we use this fact: two sets can overlap only if the end-points overlap, i.e., suppose A = {a1, ..., aN} and B = {b1, ..., bN}. A and B can't overlap if (aN < b1) || (bN < a1). This can be used to eliminate a number of comparisons. But in the worst case all ranges could overlap and we may have to look at all sets bringing the worst case to the above. Also, the SortedSet::Overlaps function will likely do the above comparison internally.
With extra memory (using a hash / map), you can do better. Consider the following analogy: Suppose you plot the 'range' of the sets on a number line by plotting the smallest and largest elements and the numbers in between. All you need to know is to check if the same point has been plotted twice. Building from that, here's a possible way: (I don't know the C# equivalent for this algo)
Create a hashmap M from int -> {set name}. So if an element '5' belongs to set '3', we say M[5] --> {3}.
Loop through all elements in all sets.
If a map already exists, you have an overlap between the current set (say 17) being looped and the set value present in the map. Also add the new set to the RHS. So for the element above, we'll see M[5] --> {3, 17}
The time complexity of the above is O(n * (cost of insertion into set)) . (It's actually n * (cost of hash lookup) * (cost of insertion into set) but we can assume for the sake of this problem that a hash has constant lookup / insertion time)
Cost of insertion into set is O(log(size of set)). The size of the set could be 'n' in the worst case as all sets may be overlapping with each other. But if many sets are not likely to overlap we could assume constant time for it making the time complexity into O(n).
Note that the above solution does not use the fact that the sets are themselves sorted since we are not making use of ordering.

Array with negative indexes

I have an array which I'm using to store map data for a game I'm working on.
MyMapType[,,] map;
The reason I'm using a fixed array instead of a Collection is because fixed arrays work very much faster.
Now my problem is, I'd like to have support for negative z levels in the game. So I'd like to be able to access a negative index.
If this is not possible, I thought of a pair of other solutions.
I was thinking as a possible solution to have ground-level as some arbitrary number (say 10), and anything less than 10 could be considered negative. But wouldn't this make the array 10 times larger for nothing if its not in use?
Another solution I considered was to 'roll my own' where you have a Dictionary of 2D arrays, with the Z level held in the List as the index. But this is a lot more work and I'm not sure if its slow or not.
So to summarise - any way of creating an array which supports a negative index? And if there's not - is there a clean way of 'emulating' such behaviour without sacrificing too much CPU time or RAM - noting that these are game maps which could end up large AND need to be accessed constantly.
replace your arrays with a class:
class MyArray {
private MyMapType[] myArray = new myMapType[size]
MyMapType this[index] {
get{return myArray[index + offset];}
}
}
you can set the size and the offset in the constructor or even change it at will.
Building on this example here is another version:
class MyArray {
private MyMapType[] positives = new myMapType[size]
private MyMapType[] negatives = new myMapType[size-1]
MyMapType this[index] {
get{return index >= 0 ? positives[index] : negateves[1-index];}
}
}
It does not change the fact that you need to set the size for both of them. Honestly I like the first one better
If you want "negative" indexes C# 8 now supports it.
var words = new string[]
{
// index from start index from end
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumps", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
}; // 9 (or words.Length) ^0
So the to call the negative one would be like this
words[^1]
See this link
So in your case the middle element could be the zero Z
Use the Dictionary class, since you can assign whatever values you want for either the key or value. While I'm not sure how this would work for the 3-dimensional array that you showed above, I can show how this would work if this were a 1-dimensional array, and you can infer how to best make use of it:
MyMapType[] map;
//map is filled with w/e data
Dictionary<int, MyMapType> x = new Dictionary<int, MyMapType>();
x[-1] = //(map data for whatever value is for the negative value);
x[0] = map[0]
//(etc...)
Could you try to store a list of MyMapTime[,] in two lists:
one for z values of greater than or equal to 0
and second of negative z-values.
The index of the tables would be the value of z.
Having this would let you access quickly the xy-values for specific z-level.
Of course the question is: what are your z-values? Are there sparse or dense.
Even for sparse values you would end up with an array holding null values for [,].
I'd like to note here that dictionaries allow for negative indexes
and a 2D dictionairy can solve problems like these too, just think about the datastructure and if you can live with a dictionary
note that dictionaries and lists are used in different scenario's.
and their speed depends on what functions are used on them

Implementation of array with negative indices

I am making a game with a world that extends infinitely in every direction. This means that you can be at position X:50, Y:50 or X:-50, Y:-50. But... I can't really do that with a normal C# List...
All the ideas I've come up with seem to be too complicated/inefficient to work...
The easiest way to implement infinite grid is using a sparse matrix with a dictionary with an x,y pair as the key and the data you want to store as the values. This is fast, easy to implement, and memory friendly if your grid is sparse.
Another way is a linked grid (similar to linked list, but with pointers to 4 directions), or a tile-based approach to reduce the overhead of linked grid (a tile is a linked grid of NxN arrays). Implementation of tiles is quite complicated, but is a good tradeoff between memory and performance for very dense grids.
But my personal favorite approach is to use the even-odd transformation. So odd indices are positive, while even numbers are negative. To transform from virtual index to the physical index, you use the formula p = abs(v * 2) - (v > 0 ? 1 : 0) and to convert physical to virtual index you do v = (p % 2 == 1 ? +1 : -1) * ((2*p + 3) / 4). This relation arises because there is one to one and onto relation (bijection) between natural numbers and integers (0 <-> 0), (1 <-> 1), (2 <-> -1), (3 <-> 2), (4 <-> -2), (5 <-> 3), (6 <-> -3), .... This approach is fast, simple and elegant, but not very great memory wise when you have very sparse grid with items extremely far from the center line.
Unless you have a TON (yes, a TON of bits...) of cells, you can use dictionaries. Combine that with a System.Drawing.Point as the key, and you get a good thing going on:
Dictionary<Point,YourGridObject> myMap = new Dictionary<Point,YourGridObject>();
Edit: In addition to the dictionary, each cell can have a reference to it's adjacent cells, this way you can use the dictionary to directly go "somewhere", but then navigate with the adjacent. I used that way to implement an A* pathfinding algorithm in an hex grid.
Edit 2:
For example, if you then want to access a specific coordinate, you can simply
var myTile = myMap[new Point(25, -25)];
Then, you want to get the East tile, you can
var eastTile = myTile.East;
Your grid object could also implement an offset method so you could get the 'West 2, North 5' tile by
var otherTile = myTile.Offset(-2, 5);
How about using two List underneath for expansions in two different directions?
I'm not certain if this is more complicated than you want to deal with, but have you considered using polar coordinates instead of cartesian? There are no negative numbers in that coordinate system. I realize that the coversion is difficult at first, but once you wrap your head around it, it becomes second nature.
You could use Dictionary, which has all the capability of an array except with negative indexes obviously.
Computers cannot store infinite arrays.
There must be a boundary to your array, remind that somewhere in code you declared a specific size during initialization of your array.
Perhaps you resize it somewhere, but that still leaves an number range from 0..to.. max.
So what you should do, write a function that allows for relatively positioning in such a map. So you store your current map[x,y] as a position.
And your able to go up, by having a function that add/substracts from your current position relativly.
This keeps your code easier to understand too.
If your not dealing with game maps but number ranges, lets say vectors
you could create a list of n points, or a 2d dictionary.
I'm posting it here, cause your problem might lead people to writing wrong code.
Also adding for other people in situations where there is a border around a map (typical in games scenario, and image manipulation.
where your data goes from [-1..width+1] just dimension it as [0,width+2]
then loop trough it starting 'for (int x = 1; x < Width+1; x++)'

Game level read from file in XNA

I've been working on a tile based map engine for my game project in Xna C#. The system, like most others, uses a digit corresponding to a tile in a tileset mapped to a specific position on screen. This works fine, but requires every cell on screen to have a number manually entered. Instead, I've decided to have level layouts read from a .txt containing the number of each tile in the position it would be ingame, like so:
1111
0110
1001
1100
Where 1 is grass and 0 is dirt. Again, I'm aware this is a common technique. The code I have written can read each line and set the next position in the first column to the corresponding tile graphic. This is fine, but it does not help with the rest of the map. I've been searching and cannot find how you would split each number in a row into a separate number, so that the first line would read (0,0) = 1, (0,1) = 1, etc, so I can then match the coordinates to the x and y position on the map, and the value to the type of tile.
So what I need is the ability to assign a 2d array corresponding to the current position (how many characters left in the file, how many lines down in the .txt file), so I can just run two branched for loops (x and y) for every tile in the level ie:
for (x=0; x<levelwidth; x++)
{
for (y=0; y<levelheight; y++)
{
Row[x].Column[y].Tile = Convert.ToInt32(filepos[x,y]);
}
}
You don't want to use 2D arrays because of heavy performance issues.
Also, you probably want to use a separator between tile numbers, like this
1,1,1,1
1,0,1,1
for two reasons; 1 you can use more than 10 different tiles, and 2 you can then use String.Split() and Int.Parse() in order to get your tile IDs and build your map.
In order to use a 1D array, instead of doing myMap[x][y], you do myMap[y*mapWidth+x].
I switched to using XML so that I could more easily edit and read the file. That also gave me a great way of indicating the end of a row of tiles in my map as well as an easy way of identifying up front just how many columns/rows my map had prior to the reader loading it in the game.
The sample for the code can be found on my site in the "Looks Level to Me" sample and it may be that it will help get some ideas for how to change your current approach.
While the commas are the best approach you can also use .substring to take it apart if things are of fixed length.

How do i define starting position of listbox?

I want to define the listbox rows to start at 1, not the default 0. How do i do it ?
You dont. You basically learn to work within the context of the environment you use. WPF defines table positions in general to start at 0.
Feel free to program your own WPF replacement.
If you are determined to do it, I would make a method
private int ListIndex(int index){
return index - 1;
}
And then use ListIndex anywhere you index into the list, but as others pointed out, you really should shift your mindset to deal with 0 based indexes, as they are a standard in most programming situations.
This is really an issue of why or why not you should begin indices (of any kind, for that matter) from 0. See this post about the very topic. There are, arguably, some good reasons for starting an index from 0.
There are also some legacy technical reasons. For example, in C, the array was actually a pointer to the first element of the array, and the form array[i] is equal to *(array + i), meaning that what the index really refers to is the offset from the first element of the array. Thus, a 0 offset references the first element, and 1 offset references the second element, and so on.
It's all about mathematical beauty.
In simple words, you can't do that buddy.

Categories

Resources