Taking array as an input to function in Haskell - arrays

I'm trying to learn Haskell and I stumbled upon a problem in my Haskell code. I have a function,
main = print (qSort [distance (3,4), distance (1,2), distance (2,2)])
distance :: (Floating a ) => (a,a) -> (a,a,a)
distance (x2 , y2) = (x2*x2 + y2*y2, x2, y2)
that calculates distance between (0,0) and given point. How can change it to something like:
main = print (qSort (distance [(3,4),(1,2),(2,2)]))
so that distance can take a whole array as input?
Also, what way will be the best to try and get the points as input from the user? Looking at examples I can't really think of a way to get points.
I've tried fiddling with square brackets, but I keep getting errors. Any help would be appreciated!

Try putting map distance instead of distance in the second code.
But you have to lookup and understand what map does!
In this case, map is telling distance Hey, man, you're promoted! Yeah, you don't just work on loosers pairs, (a,a); you work on lists of them, [(a,a)], all at once!
(The technical term for promoted is lifted, btw.)
If you're really at the start, I suggest that you go though some tutorial/book. LYAH is a very good place to start.

Related

Differences in Differentiation Implementations in MATLAB

I'm trying to find the (numerical) curvature at specific points. I have data stored in an array, and I essentially want to find the local curvature at every separate point. I've searched around, and found three different implementations for this in MATLAB: diff, gradient, and del2.
If my array's name is arr I have tried the following implementations:
curvature = diff(diff(arr));
curvature = diff(arr,2);
curvature = gradient(gradient(arr));
curvature = del2(arr);
The first two seem to output the same values. This makes sense, because they're essentially the same implementation. However, the gradient and del2 implementations give different values from each other and from diff.
I can't figure out from the documentation precisely how the implementations work. My guess is that some of them are some type of two-sided derivative, and some of them are not two-sided derivatives. Another thing that confuses me is that my current implementations use only the data from arr. arr is my y-axis data, the x-axis essentially being time. Do these functions default to a stepsize of 1 or something like that?
If it helps, I want an implementation that takes the curvature at the current point using only previous array elements. For context, my data is such that a curvature calculation based on data in the future of the current point wouldn't be useful for my purposes.
tl;dr I need a rigorous curvature at a point implementation that uses only data to the left of the point.
Edit: I kind of better understand what's going on based on this, thanks to the answers below. This is what I'm referring to:
gradient calculates the central difference for interior data points.
For example, consider a matrix with unit-spaced data, A, that has
horizontal gradient G = gradient(A). The interior gradient values,
G(:,j), are
G(:,j) = 0.5*(A(:,j+1) - A(:,j-1)); The subscript j varies between 2
and N-1, with N = size(A,2).
Even so, I still want to know how to do a "lefthand" computation.
diff is simply the difference between two adjacent elements in arr, which is exactly why you lose 1 element for using diff once. For example, 10 elements in an array only have 9 differences.
gradient and del2 are for derivatives. Of course, you can use diff to approximate derivative by dividing the difference by the steps. Usually the step is equally-spaced, but it does not have to be. This answers your question why x is not used in the calculation. I mean, it's okay that your x is not uniform-spaced.
So, why gradient gives us an array with the same length of the original array? It is clearly explained in the manual how the boundary is handled,
The gradient values along the edges of the matrix are calculated with single->sided differences, so that
G(:,1) = A(:,2) - A(:,1);
G(:,N) = A(:,N) - A(:,N-1);
Double-gradient and del2 are not necessarily the same, although they are highly correlated. It's all because how you calculate/approximate the 2nd-oder derivatives. The difference is, the former approximates the 2nd derivative by doing 1st derivative twice and the latter directly approximates the 2nd derivative. Please refer to the help manual, the formula are documented.
Okay, do you really want curvature or the 2nd derivative for each point on arr? They are very different. https://en.wikipedia.org/wiki/Curvature#Precise_definition
You can use diff to get the 2nd derivative from the left. Since diff takes the difference from right to left, e.g. x(2)-x(1), you can first flip x from left to right, then use diff. Some codes like,
x=fliplr(x)
first=x./h
second=diff(first)./h
where h is the space between x. Notice I use ./, which idicates that h can be an array (i.e. non-uniform spaced).

Getting points along a line given heading, starting point and distance between points

I am currently working on my research and coding my theories to simulate scenarios.
I need a way to incrementally find points along a given heading (angle between a line and the positive x axis) given the heading, the starting point, and the distance between the points. The new points should be in the direction of the heading. I am somehow facing a difficulty on how I should go about doing this.
With enough time I can come up with a way myself, but given that sharpening my coding skills is not my final outcome here and I would rather spend more time experimenting with my theory, I was wondering if anyone could help me find a solution. I am working with C, so a solution in C would be preferred and not one that uses library functions available in other languages.
One solution is to create a unit vector in the direction you want
for example lets say you want 45 degrees, the unit vector would be
<1/sqrt(2), 1/sqrt(2)>. this distance would be 1 since its a unit vector so you can scale it by the distance you want per point. so lets say you want each point to be 1/3 of a unit, then you would just multiply the unit vector and get
<1/(3sqrt(2)), 1/(3sqrt(2))> and then you can just do a loop. so if you want 10 points in that direction it would just be
unitvector = calculateUnitVector()
unitvector *= distanceBetweenPoints
for(i = 0 ; i < 10; i++){
drawPoint(startPoint + unitVector * i)
}
i hope this helps.

Closest pair of points algorithm variation

I know this may be a duplicate, but it seems like a variation on the 'Closest pair of Points' algorithm.
Given a Set of N points (x, y) in the unit square and a distance d, find all pair of points such that the distance between them is at most d.
For large N the brute force method is not an option. Besides the 'sweep line' and 'divide and conquer' methods, is there a simpler solution? These pair of points are the edges of an undirected graph, that i need to traverse it and say if it's connected or not (which i already did using DFS, but when N = 1 million it never finishes!).
Any pseudocode, comments or ideas are welcome,
Thanks!
EDIT: I found this on Sedgewick book (i'm looking at the code right now):
Program 3.18 uses a two-dimensional array of linked lists to improve the running time of Program 3.7 by a factor of about 1/d2 when N is sufficiently large. It divides the unit
square up into a grid of equal-sized smaller squares. Then, for each square, it builds a linked list of all the
points that fall into that square. The two-dimensional array provides the capability to access immediately
the set of points close to a given point; the linked lists provide the flexibility to store the points where
they may fall without our having to know ahead of time how many points fall into each grid square.
We are really looking for points that are inside of a circle of center (x,y) and radius d.
The square that encloses circle is a square of center (x,y) and sides 2d. Any point out of this square does not need to be checked, it's out. So, a point a (xa, ya) is out if abs(xa - x) > d or abs (ya -yb) > d.
Same for the square that is enclosed by that circle is a square of center (x,y) and diagonals 2d. Any point out of this square does not need to be checked, it's in. So, a point a (xa, ya) is in if abs(xa - x) < (d * 1.412) or abs(ya -yb) < (d * 1.412).
Those two easy rules combined reduce a lot the number of points to be checked. If we sort the point by their x, filter the possible points, sort by their y, we come to the ones we really need to calculate the full distance.
For any given point, you can use a Manhattan distance (x-delta plus y-delta) heuristic to filter out most of the points that are not within the distance "d" - filter out any points whose Manhattan distance is greater than (sqrt(2) * d), then run the expensive-and-precise distance test on the remaining points.

Update position of a point [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 13 years ago.
My problem is this:
I have a set of points in 3D space, and their positions are updated from time to time with a certain velocity. But i need to keep a minimal distance between them.
Can you help me with this?
EDIT: I am using C for the implementation of the algorithm.
Thanks in advance.
You can also do this using a physics simulation. This gives many more possibilities, but at a higher computational cost.
For example, others here suggest detecting collisions, but in your comment to duffymo you suggest you would might like a smooth deceleration to avoid collision. In this case, you could create an inter-particle force pushing them away from each other, and then calculate your velocity at each time step using a = F/m, and v = v0 + dt a, where F is the sum of the forces of all the particles on each other. For an example inter-particle force you could use something that looks like one of these:
Calculated from the Python code below. But really anything could work as long as it gets large enough near your minimum distance (so the points never come that close together), and it's zero beyond some distance (so the points aren't always repelled from each other).
from pylab import *
def repulse(x, c, rmin=1., fmax=100):
if x<=rmin:
return fmax
try:
f = c/(x-rmin)-5.
if f<0.:
f = 0.
if f>fmax:
return fmax
except:
f = fmax
return f
x = arange(0, 100, .01)
r = 0.*x
for c in range(0, 10):
for i, xv in enumerate(x):
r[i] = repulse(xv, 2.**c)
plot(x, r)
show()
If you want to keep a minimal distance d, you can always assume the points are made up of rigid balls of radius d/2. So whenever 2 balls come in contact (i.e. the distance is ≤ d), you change the velocity assuming an elastic collision. Look up your physics textbook for how to change the velocity in case of elastic collision.
(You may need to implement a quad-tree for efficient collision detection.)
Updating position given a velocity is easy - just use a first order difference for the velocity and calculate the position at the end of the time step.
"But I need to keep a minimal distance between them" - makes no sense at all. The distance between them will be governed by the physics of the process that gives you the velocity vector. Can you describe what you're trying to do?
The first thing you need to do is to detect when distance between 2 points becomes less than your minimal distance. The second one is to move point in a way to remove collisions.
The first part is circle-to-circle collission* detection basically, so the aproaches are the same: checking distance between every moved point and other points or using continious collision detection*(if points move by some simple laws).
The second part is up to you, there are too many ways.
(*) - googleable
Determining whether two particles will collide. Suppose you have two particles A and B, and you know their positions at time 0 and their velocities. Initially they are farther apart than the distance r; you want to know if and when they will come within r of each other.
Let's define two 3D vectors R and V. R = the position of B relative to A at time 0, B.position - A.position, and V = the velocity of B relative to A, B.velocity - A.velocity. The square of the distance between A and B at time t will be
square_of_distance(t)
= abs(R + V*t)^2
= dot(R + V*t, R + V*t)
= dot(R, R) + 2 * dot(R, V*t) + dot(V*t, V*t)
= dot(R, R) + 2 * dot(R, V) * t + dot(V, V) * t^2
where dot(v1, v2) is the dot product of two vectors and abs(v) is the vector length.
This turns out to be a simple quadratic function of t. Using the quadratic formula, you can find the times t, if any, when square_of_distance(t) = r2. That will tell you if and when the particles approach each other closer than r.
Determining which of a large number of particles will collide first. Of course you can take every possible pair of particles and calculate when they collide. That's O(n2). Improving on that is harder than the simple stuff we've been doing here so far.
Since you only really need to know about the next, say, n seconds, you can calculate a bounding box for each particle's path over that period of time, extend all those boxes by r in each direction, and see which ones, if any, overlap. This can be done using a modified kd-tree. Overlapping bounding boxes do not necessarily indicate actual collisions, only potential collisions. These potential collisions still have to be checked mathematically to see if there are any real collisions; this is just a way to reduce the amount of checking from O(n2) to something more manageable.

Angle at corner of two lines

I search for the fastest or simplest method to compute the outer angle at any point of a convex polygon. That means, always the bigger angle, whereas the two angles in question add up to 360 degrees.
Here is an illustration:
Now I know that I may compute the angles between the two vectors A-B and C-B which involves the dot product, normalization and cosine. Then I would still have to determine which of the two resulting angles (second one is 180 degrees minus first one) I want to take two times added to the other one.
However, I thought there might be a much simpler, less tricky solution, probably using the mighty atan2() function. I got stuck and ask you about this :-)
UPDATE:
I was asked what I need the angle for. I need to calculate the area of this specific circle around B, but only of the polygon that is described by A, B, C, ...
So to calculate the area, I need the angle to use the formula 0.5*angle*r*r.
Use the inner-product (dot product) of the vectors describing the lines to get the inner angle and subtract from 360 degrees?
Works best if you already have the lines in point-vector form, but you can get vectors from point-to-point form pretty easily (i.e. by subtraction).
Taking . to be the dot product we have
v . w = |v| * |w| * cos(theta)
where v and w are vectors and theta is the angle between the lines. And the dot product can be computed from the components of the vectors by
v . w = SUM(v_i * w_i : i=0..3) // 3 for three dimensions. Use more or fewer as needed
here the subscripts indicate components.
Having actually read the question:
The angle returned from inverting the dot-product will always be less than 180 degrees, so it is always the inner angle.
Use this formula:
beta = 360° - arccos(<BA,BC>/|BA||BC|)
Where <,> is the scalar product and BA (BC) are the vectors from B to A (B to C).
I need to calculate the area of the circle outside of the polygon that is described by A, B, C, ...
It sounds like you're taking the wrong approach, then. You need to calculate the area of the circumcircle, then subtract the area of the polygon.
If you need the angle there is no way around normalizing the vectors and do a dot or cross-product. You often have a choice if you want to calculate the angle via asin, acos or atan but in the end that does not make a difference to execution speed.
However, It would be nice if you could tell us what you're trying to archive. If we have a better picture of what you're doing we might be able to give you some hints how to solve the problem without calculating the angle at the first place.
Lots of geometric algorithms can be rewritten to work with cross and dot-products only. Euler-angles are rarely needed.

Resources