I have the following code:
ray_points = [np.array([r1_1, r2_1, r3_1, r4_1]),np.array([r1_2, r2_2, r3_2, r4_2]),np.array([r1_3, r2_3, r3_3, r4_3])]
The list ray_points contains the coordinates of light rays. For this example, I have four light rays (r1,r2,r3,r4). Each time after I've located the next coordinates for the light rays (they have 'new' coordinates once they travel and hit another surfaces), I will append the list ray_points with a new array of size (4L,3L), (4L stands for the four light rays, 3L stands for the three spacial coordinates). So for example, r1_2 is an array with length three and means the 2nd coordinates of ray r1, r3_3 means the 3rd coordinates of ray r3, and so on.
My previous approach is to have N different lists, each contains the coordinates using arrays with shape (3L,1L), for N different rays. Now I use a (4L,3L) array to store all the coordinates of the light rays for each new intersection because I want to 'vectorize' my code in order to speed things up. (Imagine if I have like 100k light rays). Everytime when I want to calculate the next coordinates, next refracted directions, etc, I will just past the most previous coordinates of the ray, which is simple ray_points[-1] to my functions and the functions to calculate everything directly to this array, which is really significantly faster than what I did previously by creating N different lists and looping each light ray for calculation.
Now the problem is that, if different rays have different number of intersection of surfaces, and hence different number of new coordinates, I run into trouble. For instance, ray r1 has refracted 10 times is already terminated, so I will only have r1_1, r1_2 ... r1_10. But I still need to keep track of other rays r2,r3,r4. Since I use a single 4X3 array that contains my coordinates for the 4 rays, I have to keep adding coordinates to r1. I can use keep the new points/directions of r1 the same, but then I am just wasting memory, and imagine if all the rays are terminated and I have a single ray that is keep travelling and having new coordinates, then most of the elements of ray_points are actually redundant.
I would like to know how I should set up my initial codes so that I can use this vectorized approach to speed things up, yet I can still keep the advantage of the original approach - treat each ray separately so I can handle rays with different number of new coordinates.
Related
I want to sample a certain number of points in each region of the image according to a segment map(like what the SLIC algorithm produces, it's a map with the same size as the image, containing integers from 0 to num_segment indicating which segment each pixel belongs to).
Currently, I write my own code as follows:
For i in range(0, num_segment):
find the (indexes of the)pixels that belong to the ith segment using torch.where
picking out those pixels and forming a 1-d tensor
use torch.Upsample to uniformly sample n_sample points for the ith segment
stack all the sampled points to form a large 2-d tensor which each row represent selected points belong to one segment, and it has n_sample rows.
I not only want the original value from the image for each selected point, but their indexes are also needed.
I drew a picture to illustrate.
So, my question is, is there a native way to implement this in PyTorch? The above code runs a little bit slow, maybe the For-loop slows down the speed. And if possible, since all the sampling process are independent of each other, how can I speed up the process?
Generally, I have ~400 segments, and I want to sample 20~50 points for each segment.
I have two coordinate systems for each record in my dataset. Lat-lon coordinates and what I suppose is utm x-y coordinates.
50% of my dataset only has x-y data without lat-lon, viceversa is 6%.
There is a good portion of the dataset that has both (33%) for each single record.
I wanted to know if there is a way to take advantage of the intersection (and maybe the x-y only part, since it's the biggest) to obtain a full dataset with only one coordinate system that makes sense. The problem is that after a little bit of preprocessing, they look "relaxed" in a different way and the intersection doesn't really match. The scatter plot shows what I believe to be a non linear, warped relationship from one system of coordinates to another. With this, I mean that normalizing them both to [0;1] and centering them to (0,0) (by subtracting the mean), gives two slightly different point distributions, and apparently a coefficient multiplication to scale one down to look like the other is not enough to get them to match completely. Looks like some more complicated relationship between the two.
I also tried to use an external library called utm to convert the lat-long coordinates to x-y to have a third pair of attributes (let's call it my_xy), only to find out that is not matching even one of the first two systems, instead it shows another slight warp.
Notes: When I say I do not have data from one coordinate system, assume NaN.
Furthermore, I know the warping could be a result of the fundamental geometrical differences between latlon and xy systems, but I still do not know what else I could try, if the utm conversion and the scaling did not work.
Blue: latlon, Red: original xy, Green: my_xy calculated from latlon
I split de world in X random polygons.
Then I am given a coordinate C1, for instance (-21.45, 7.10), and I want to attribute the right polygon to this coordinate.
The first solution is to apply my ‘point_in_polygon’ algorithm (given a set of coordinates that defines a polygon and a coordinate that defines a point, tell me if the point is inside or not) on each polygon until I find the right one.
But that is very expensive if I have a lot of points to put in a lot of polygons.
An improvement on that relies on the following idea:
To optimise the search, I create a grid (a collection) with a step n, k where I already attribute each pair of coordinates such that:
for i=-180 to 180 step n
for j = -90 to 90 step k
grid.add(i,j)
Then I create a dictionary, and for each pair in the collection I find the corresponding polygon
For each g in grid
For each p in polygons
If point_in_polygon(g,p) == True
my_dict(g) = p
Then, when I receive C1, I look for the closest coordinate in my grid, let’s say g1.
Thanks to my_dict, I can get quickly p1 = my_dict(g1)
Then I compute point_in_polygon(C1, p1) which is likely to be true. If it’s not, I find the closest g which is assigned to a different polygon, and I redo a test. Etc. until I have found the right polygon.
Now, the question is: what is the optimal n, k to create the grid?
So that I can find the right polygon in the minimum number of steps.
I don’t want it too low, because the search of the closest g which is assigned to a different polygon might be expensive.
I don’t want it too high as well, because then I might be missing some polygons and then the search never converges.
My intuition is that the smallest polygon is going to give the steps.
I am not sure if this is a programming problem, a maths problem, or just something I can find empirically, that's why I ask it here.
Any inputs appreciated!
Let me suggest a slight modification to your grid. Currently, you store for each cell the polygon that the cell's center belongs to. Instead, store all the polygons that overlap the cell. Then, whenever you see that a cell has only a single overlapping polygon, you don't need to do any inclusion testing. The grid can be built by methods of conservative rasterization (note that the referenced article is not focused on conservative but rather general rasterization).
The efficiency of your grid correlates with the ratio of single-polygon cells and total cells (because this is the probability of not having to perform polygon-inclusion tests). The storage itself is pretty cheap. You can use a dense array and get constant access to the cells. Hence, from a theoretical point of view, you should have as many cells as possible (because as you have more cells, the single-polygon cell ratio increases). In practice, you might find that cache and other memory effects might make large grids impractical. However, there is no good way to know other than test. So, just try with a couple of sizes on a few different machines and try to find a good fit.
If I had to guess, I would say that your cells should be square and have an area of about 1% - 5% of the average polygon area. Also, more compact polygons can be handled more efficiently than many long and thin polygons.
Pick any point and draw a line straight down from that point. The first polygon edge you hit tells you what polygon the point is in.
So, if you don't want to do polygon tests, then instead of dividing the space into a regular grid, first cut it into strips with vertical cuts that go through all polygon intersections.
Now, within each strip none of the polygon edges cross or end, so you can make an ordered list of all those edges from bottom to top.
If you want to find the polygon that contains a point, then, do a binary search using the x coordinate to find the proper strip. Then in the list of edges that span the strip, you can do a binary search using the y coordinate to find the closest one underneath the point, and that tells you what polygon the point is in.
Google 'trapezoidal decomposition' to find lots of information about similar techniques.
Currently, if I want to compare pressure under each of the paws of a dog, I only compare the pressure underneath each of the toes. But I want to try and compare the pressures underneath the entire paw.
But to do so I have to rotate them, so the toes overlap (better). Because most of the times the left and right paws are slightly rotated externally, so if you can't simply project one on top of the other. Therefore, I want to rotate the paws, so they are all aligned the same way.
Currently, I calculate the angle of rotation, by looking up the two middle toes and the rear one using the toe detection then I calculate the the angle between the yellow line (axis between toe green and red) and the green line (neutral axis).
Now I want to rotate the array would rotate around the rear toe, such that the yellow and green lines are aligned. But how do I do this?
Note that while this image is just 2D (only the maximal values of each sensor), I want to calculate this on a 3D array (10x10x50 on average). Also a downside of my angle calculation is that its very sensitive to the toe detection, so if somebody has a more mathematically correct proposal for calculating this, I'm all ears.
I have seen one study with pressure measurements on humans, where they used the local geometric inertial axis method, which at least was very reliable. But that still doesn't help me explain how to rotate the array!
If someone feels the need to experiment, here's a file with all the sliced arrays that contain the pressure data of each paw. To clarfiy: walk_sliced_data is a dictionary that contains ['ser_3', 'ser_2', 'sel_1', 'sel_2', 'ser_1', 'sel_3'], which are the names of the measurements. Each measurement contains another dictionary, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (example from 'sel_1') which represent the impacts that were extracted.
Why would you do it that way? Why not simply integrate the whole region and compare? In this case you'll get a magnitude of the force and you can simply compare scalars which would be much easier.
If you need to somehow compare regions(and hence that's why you need to align them) then maybe attempt a feature extraction and alignment. But this would seem to fail if the pressure maps are not similar(say someone is not putting much wait on one foot).
I suppose you can get really complex but it sounds like simply calculating the force is what you want?
BTW, you can use a simple correlation test to find the optimal angle and translation if the images are similar.
To do this you simply compute the correlation between the two different images for various translations and rotations.
Using the Python Imaging Library, you can rotate an array with for example:
array(Image.fromarray(<data>).rotate(<angle>, resample=Image.BICUBIC))
From there, you can just create a for loop over the different layers of your 3D array.
If you have your first dimension as the layers, then array[<layer>] would return a 2D layer, thus:
for x in range(<amount of layers>):
layer = <array>[i]
<array>[i] = (Image.fromarray(layer).rotate(<angle>, resample=Image.BICUBIC))
Results by #IvoFlipse, with a conversation suggesting:
Putting the array in a bigger array to remedy the darker background.
Look into resampling, perhaps scale the array first.
Moving the rear toe towards the middle allows you to rotate around that instead.
A smaller image can be determined by finding the borders and positioning them in a 15x15 again.
I have a large collection of rectangles, all of the same size. I am generating random points that should not fall in these rectangles, so what I wish to do is test if the generated point lies in one of the rectangles, and if it does, generate a new point.
Using R-trees seem to work, but they are really meant for rectangles and not points. I could use a modified version of a R-tree algorithm which works with points too, but I'd rather not reinvent the wheel, if there is already some better solution. I'm not very familiar with data-structures, so maybe there already exists some structure that works for my problem?
In summary, basically what I'm asking is if anyone knows of a good algorithm, that works in Python, that can be used to check if a point lies in any rectangle in a given set of rectangles.
edit: This is in 2D and the rectangles are not rotated.
This Reddit thread addresses your problem:
I have a set of rectangles, and need to determine whether a point is contained within any of them. What are some good data structures to do this, with fast lookup being important?
If your universe is integer, or if the level of precision is well known and is not too high, you can use abelsson's suggestion from the thread, using O(1) lookup using coloring:
As usual you can trade space for
time.. here is a O(1) lookup with very
low constant. init: Create a bitmap
large enough to envelop all rectangles
with sufficient precision, initialize
it to black. Color all pixels
containing any rectangle white. O(1)
lookup: is the point (x,y) white? If
so, a rectangle was hit.
I recommend you go to that post and fully read ModernRonin's answer which is the most accepted one. I pasted it here:
First, the micro problem. You have an
arbitrarily rotated rectangle, and a
point. Is the point inside the
rectangle?
There are many ways to do this. But
the best, I think, is using the 2d
vector cross product. First, make sure
the points of the rectangle are stored
in clockwise order. Then do the vector
cross product with 1) the vector
formed by the two points of the side
and 2) a vector from the first point
of the side to the test point. Check
the sign of the result - positive is
inside (to the right of) the side,
negative is outside. If it's inside
all four sides, it's inside the
rectangle. Or equivalently, if it's
outside any of the sides, it's outside
the rectangle. More explanation here.
This method will take 3 subtracts per
vector * times 2 vectors per side,
plus one cross product per side which
is three multiplies and two adds. 11
flops per side, 44 flops per
rectangle.
If you don't like the cross product,
then you could do something like:
figure out the inscribed and
circumscribed circles for each
rectangle, check if the point inside
the inscribed one. If so, it's in the
rectangle as well. If not, check if
it's outside the circumscribed
rectangle. If so, it's outside the
rectangle as well. If it falls between
the two circles, you're f****d and you
have to check it the hard way.
Finding if a point is inside a circle
in 2d takes two subtractions and two
squarings (= multiplies), and then you
compare distance squared to avoid
having to do a square root. That's 4
flops, times two circles is 8 flops -
but sometimes you still won't know.
Also this assumes that you don't pay
any CPU time to compute the
circumscribed or inscribed circles,
which may or may not be true depending
on how much pre-computation you're
willing to do on your rectangle set.
In any event, it's probably not a
great idea to test the point against
every rectangle, especially if you
have a hundred million of them.
Which brings us to the macro problem.
How to avoid testing the point against
every single rectangle in the set? In
2D, this is probably a quad-tree
problem. In 3d, what generic_handle
said - an octree. Off the top of my
head, I would probably implement it as
a B+ tree. It's tempting to use d = 5,
so that each node can have up to 4
children, since that maps so nicely
onto the quad-tree abstraction. But if
the set of rectangles is too big to
fit into main memory (not very likely
these days), then having nodes the
same size as disk blocks is probably
the way to go.
Watch out for annoying degenerate
cases, like some data set that has ten
thousand nearly identical rectangles
with centers at the same exact point.
:P
Why is this problem important? It's
useful in computer graphics, to check
if a ray intersects a polygon. I.e.,
did that sniper rifle shot you just
made hit the person you were shooting
at? It's also used in real-time map
software, like say GPS units. GPS
tells you the coordinates you're at,
but the map software has to find where
that point is in a huge amount of map
data, and do it several times per
second.
Again, credit to ModernRonin...
For rectangles that are aligned with the axes, you only need two points (four numbers) to identify the rectangle - conventionally, bottom-left and top-right corners. To establish whether a given point (Xtest, Ytest) overlaps with a rectangle (XBL, YBL, XTR, YTR) by testing both:
Xtest >= XBL && Xtest <= XTR
Ytest >= YBL && Ytest <= YTR
Clearly, for a large enough set of points to test, this could be fairly time consuming. The question, then, is how to optimize the testing.
Clearly, one optimization is to establish the minimum and maximum X and Y values for the box surrounding all the rectangles (the bounding box): a swift test on this shows whether there is any need to look further.
Xtest >= Xmin && Xtest <= Xmax
Ytest >= Ymin && Ytest <= Ymax
Depending on how much of the total surface area is covered with rectangles, you might be able to find non-overlapping sub-areas that contain rectangles, and you could then avoid searching those sub-areas that cannot contain a rectangle overlapping the point, again saving comparisons during the search at the cost of pre-computation of suitable data structures. If the set of rectangles is sparse enough, there may be no overlapping, in which case this degenerates into the brute-force search. Equally, if the set of rectangles is so dense that there are no sub-ranges in the bounding box that can be split up without breaking rectangles.
However, you could also arbitrarily break up the bounding area into, say, quarters (half in each direction). You would then use a list of boxes which would include more boxes than in the original set (two or four boxes for each box that overlapped one of the arbitrary boundaries). The advantage of this is that you could then eliminate three of the four quarters from the search, reducing the amount of searching to be done in total - at the expense of auxilliary storage.
So, there are space-time trade-offs, as ever. And pre-computation versus search trade-offs. If you are unlucky, the pre-computation achieves nothing (for example, there are two boxes only, and they don't overlap on either axis). On the other hand, it could achieve considerable search-time benefit.
I suggest you take a look at BSP trees (and possible quadtrees or octrees, links available on that page as well). They are used to partition the whole space recursively and allow you to quickly check for a point which rectangles you need to check at all.
At minimum you just have one huge partition and need to check all rectangles, at maximum your partitions get so small, that they get down to the size of single rectangles. Of course the more fine-grained the partition, the longer you need to walk down the tree in order to find the rectangles you want to check.
However, you can freely decide how many rectangles are suitable to be checked for a point and then create the corresponding structure.
Pay attention to overlapping rectangles though. As the BSP tree needs to be precomputed anyways, you may as well remove overlaps during that time, so you can get clear partitions.
Your R-tree approach is the best approach I know of (that's the approach I would choose over quadtrees, B+ trees, or BSP trees, as R-trees seem convenient to build in your case). Caveat: I'm no expert, even though I remember a few things from my senior year university class of algorithmic!
Why not try this. It seems rather light on both computation and memory.
Consider the projections of all the rectangles onto the base line of your space. Denote that set of line intervals as
{[Rl1, Rr1], [Rl2, Rr2],..., [Rln, Rrn]}, ordered by increasing left coordinates.
Now suppose your point is (x, y), start a search at the left of this set until you reach a line interval that contains the point x.
If none does, your point (x,y) is outside all rectangles.
If some do, say [Rlk, Rrk], ..., [Rlh, Rrh], (k <= h) then just check whether y is within the vertical extent of any of these rectangles.
Done.
Good luck.
John Doner