query about hoares partition : boundary check - quicksort

I found lots of the hoare partition implementation for quick sorting, it didn't do the boundary check while finding the larger item or smaller item comparing to the pivot item. anyone know why?
For example, below is from https://www.techiedelight.com/quick-sort-using-hoares-partitioning-scheme/. While increasing i, decreasing j, the a[i] might be out of upper boundary when the array a is already a descending array.
# Partition using Hoare's Partitioning scheme
def partition(arr, low, high):
pivot = arr[low]
(i, j) = (low - 1, high + 1)
while True:
while True:
i = i + 1
if arr[i] >= pivot:
break
while True:
j = j - 1
if arr[j] <= pivot:
break
if i >= j:
return j
swap(arr, i, j)
my understanding is to add the boundary check for i, and j, like below:
# Partition using Hoare's Partitioning scheme
def partition(arr, low, high):
pivot = arr[low]
(i, j) = (low - 1, high + 1)
while True:
while True:
i = i + 1
if arr[i] >= pivot and i < high:
break
while True:
j = j - 1
if arr[j] <= pivot and j > low:
break
if i >= j:
return j
swap(arr, i, j)

Related

How to realise the backflow from one volume to the upper volume by modelica language?

It is a simple idea that I Want to solve the same equations in a finite volume when the variable x of next volume is computed smaller than 0. Because the characteristic of the modelica language, it is really hard for me to realise the loop. I hope someone can help me with this. Thanks!
model Model
parameter Real L = 10;
parameter Real r = 5;
parameter Integer N = 20;
Real x[N](each start = 0);
equation
if noEvent(x[1] >= 0 and x[1] < L) then
der(x[1]) = r;
else
der(x[1]) = 0;
end if;
for i in 2:N loop
if noEvent(x[i - 1] >= L and x[i] >= 0 and x[i] < L) then
der(x[i]) = r - 1 * time;
elseif noEvent(x[i] < 0) then
der(x[i - 1]) = r - x[i - 1];
else
der(x[i]) = 0;
end if;
end for;
end model;
The code just can not dostep when time > 8s.
And the Mworks show the message:
...
Error: Failed to solve linear system at Time = 7.99999989157494
Error: Failed to solve linear system at Time = 7.99999989157489
Error: Failed to solve linear system at Time = 7.99999989157489
I have no Mworks, but Dymola. If we simulate your code in Dymola, we get the following error message:
Error: The following error was detected at time: 7.99999999711724
Error: Singular inconsistent scalar system for
der(x[2]) = ( -(if x[1] >= 10 and x[2] >= 0 and x[2] < 10 then 1*time-5 else (if x[2] < 0 then der(x[1])+x[1]-5 else 0.0)))/((if x[1] >= 10 and x[2] >= 0 and x[2] < 10 then 1.0 else (if x[2] < 0 then 0.0 else 1.0))) = -5/0
Looking in detail at the equation for x[2], we see that for x[2] < 0 we have
der(x[2]) = - (der(x[1])+x[1]-5) / 0
This originates from the elseif in your for loop, where you write:
elseif noEvent(x[i] < 0) then
der(x[i - 1]) = r - x[i - 1];
Here you only use the derivative of the previous vector element, while you are using der(x[i]) in the other if branches.
The modelica tool needs valid equations in all if branches.
My guess is, that it adds 0 * der(x[i]) to be able to create a solvable equation set.
So your equation in the elseif branch is extended by the tool to
0 * der(x[i]) + der(x[i - 1]) = r - x[i - 1]
And after causalization of the equations we get:
der(x[i]) := - (der(x[i - 1]) - r + x[i - 1]) / 0
To avoid the division by zero, you have to rewrite your for loop such that you are using der(x[i]) in every branch of the if statement. Here is an example how this could look like:
model Model2
parameter Real L = 10;
parameter Real r = 5;
parameter Integer N = 20;
Real x[N](each start = 0);
equation
if x[1] >= 0 and x[1] < L then
der(x[1]) = r;
else
der(x[1]) = 0;
end if;
for i in 2:N-1 loop
if x[i - 1] >= L and x[i] >= 0 and x[i] < L then
der(x[i]) = r - 1 * time;
elseif x[i+1] < 0 then
der(x[i]) = r - x[i];
else
der(x[i]) = 0;
end if;
end for;
if x[N - 1] >= L and x[N] >= 0 and x[N] < L then
der(x[N]) = r - 1 * time;
else
der(x[N]) = 0;
end if;
end Model2;
The elseif branch now looks ahead at the next element. This requries that the the last element of xis handled in seperate equations, like you already do with the first one.
This code now simulates beyond 8s, but there seem to be some troubles with your equations. Nothing is happening after 8s, because x[2] never reaches L. I guess you have to rethink the equation der(x[i]) = r - 1 * time (or the complete model) to solve that.
Note that I also removed all the noEvent() operators, because I expect your model to run better with state events.

Convert vector into matrix: New row when value > X

I have a question and I can't find any solution, My problem is, that i have a vector V (m x 1). V is imported data from excel and can differ in leangth. It contains sequences of numbers >7000 and sequences of numbers < 7000. The sequences also can differ in leangth. Now I want to copy all values that are >7000 into a matrix. Everytime the value of V gets >7000 the matrix should start a new row. So that the new rows of the matrix won't differ in leangth, the shorter rows should be "filled up" with 0 until the leangth of the longest row is reached.
This is an example of how it should work.
`V [18x1]: [6000, 6500, 5000, 8000, 15000, 15500, 16000, 6000, 4000, 16500, 14000, 400, 5000, 6000, 9000, 12000, 13000, 5000]`
`Matrix [3x4]:
1.row [8000 15000 15500 16000]
2.row [16500 14000 0 0]
3.row [9000 12000 13000 0]`
I thought of first splitting the vector into several smaller vectors each time the value of V gets > 7000. And afterwards combining them to the desired matrix and delete all values < 7000. But this seems quite inconvenient to me.
A solution can be using for:
result = []; new_row = 1; col_num = 1; row_num = 0;
limit = 7000;
for idx = 1:length(V)
if(V(idx) > limit && new_row == 0) % case 1
result(row_num, col_num) = V(idx);
col_num = col_num + 1;
elseif(V(idx) > limit && new_row == 1) %case 2
row_num = row_num + 1; new_row = 0; col_num = 2;
result(row_num, 1) = V(idx);
elseif(V(idx) <= limit) %case 3
new_row = 1;
end
end
case 1 is true if before this a row is created and there is no V(j) < limit after the row creation.
case 2 is true if before this V(idx-1) < limit). and case 3 is true if V(idx) <= limit.

Only allow fixed number of random points in each tile

Following up on a previous question, I have code that I think should limit the number of randomly generated points in each quadrant of the total tile; however, it is not working.
n = 4;
used = [];
k = 0;
a1_count = 0;
a2_count = 0;
a3_count = 0;
a4_count = 0;
min = 1;
max = 1;
while k<n
x = rand*2;
y = rand*2;
notvalid = 0;
if (0 <= x) && (x <= 1) && (0 <= y) && (y <= 1)
a1_count = a1_count + 1;
end
if (1 < x) && (x <= 2) && (0 <= y) && (y <= 1)
a2_count = a2_count + 1;
end
if (0 <= x) && (x <= 1) && (1 < y) && (y <= 2)
a3_count = a3_count + 1;
end
if (1 < x) && (x <= 2) && (1 < y) && (y <= 2)
a4_count = a4_count + 1;
end
%%%
if (min <= a1_count) && (a1_count <= max) && (min <= a2_count) && (a2_count <= max)...
&& (min <= a3_count) && (a3_count <= max) && (min <= a4_count) && (a4_count <= max)
notvalid=1;
end
if notvalid
continue
end
used(end+1,:) = [x;y];
k = k+1;
end
I wish to generate 4 random points, and have one in each quadrant of the total area. To do this, I have a maximum and minimum number of points in each quadrant (in this case 1), and an if statement to check that the count for each tile falls within the min and max. If it doesn't, then notvalid = 0 and the loop should begin again. This function doesn't seem to work however, as the loop finishes with 4 points total and is completely random (all the counts should = 1).
Can anyone spot where I'm going wrong?
I may be missing something, but the easiest approach would probably be something like
Select N random numbers within the x/y range of the first grid cell
Repeat for all grid cells
Here is some basic code that should create N random x/y points per grid cell
% Define the grid (for demonstration purposes)
dx = 1; dy = 1;
xrange = 0:dx:2;
yrange = 0:dy:2;
% Number of points per cell
N = 1;
[lowerx, lowery] = meshgrid(xrange(1:end-1), yrange(1:end-1));
% Store all those random numbers in a cell
data = cell(size(lowerx));
for k = 1:numel(lowerx);
% Generate 4 random points within the x/y range
xcoord = (rand(N, 1) * dx) + lowerx(k);
ycoord = (rand(N, 1) * dy) + lowery(k);
data{k} = [xcoord, ycoord];
end
disp(data)
data =
[1x2 double] [1x2 double]
[1x2 double] [1x2 double]
EDIT
To address your question directly using the code that you have provided, the logic in the code in your question is a little wonky. I have rewritten your while loop to be a little clearer so we can talk through it.
while k < n
x = rand * 2;
y = rand * 2;
if y >= 0 && y < 1
if x >= 0 && x < 1
a1_count = a1_count + 1;
else
a2_count = a2_count + 1;
end
else
if x >= 0 && x < 1
a3_count = a3_count + 1;
else
a4_count = a4_count + 1;
end
end
counts = [a1_count, a2_count, a3_count, a4_count];
notValid = all(counts >= minimum) && all(counts <= maximum);
if notValid
continue;
end
used(end+1,:) = [x;y];
k = k+1;
end
So the biggest thing is your notValid check. If you actually look at what you're checking (that all your *_count variables are within the pre-specified limits), I believe that if all of those conditions are true, then the current point is valid; however you state just the opposite.
Then you basically say, that if the current x y is valid, then add it to the used list. Well this logic is fine except that you define validity backwards as I stated before.
Ok so that aside, let's look at when you think that a point is not valid. Well, then you (correctly) go to the next iteration, but you never decrement the *_count variable. So say you had 1 point in quadrant 1 already and the second iteration through the loop it's in quadrant 1 again. Well you'd add 1 to a1_count and then see that it isn't valid (a1_count exceeds max) and go to the next loop, but a1_count stays at 2 despite really only having 1 because you just rejected it.
Now, all of that aside. Let's consider the first time through your loop and look at your validity check. Since you only add one point. Your validity check can never pass (if implemented correctly) because all *_count variables except the one that was just incremented will be less than the min.
So I think what happened is you probably did the validity check correctly at first, ended up with an infite while loop, and then negated that check, didn't get an infinite loop, but as a result got an incorrect solution.
The solution that you are getting currently, is literally the first 4 times through the while loop due to the incorrect logic.
If you really like your current approach, we can clean up the code to be correct.
n = 4;
used = zeros(0,2);
minimum = 1;
maximum = 1;
counts = [0 0 0 0];
while true
x = rand * 2;
y = rand * 2;
if y >= 0 && y < 1
if x >= 0 && x < 1
quadrant = 1;
else
quadrant = 2;
end
else
if x >= 0 && x < 1
quadrant = 3;
else
quadrant = 4;
end
end
% Check to see if we can even add this point
if counts(quadrant) + 1 > maximum
continue;
end
counts(quadrant) = counts(quadrant) + 1;
used = cat(1, used, [x, y]);
isComplete = all(counts >= minimum & counts <= maximum) && ...
size(used, 1) == n;
if isComplete
break
end
end

Integer division in Scala [duplicate]

(note: not the same as this other question since the OP never explicitly specified rounding towards 0 or -Infinity)
JLS 15.17.2 says that integer division rounds towards zero. If I want floor()-like behavior for positive divisors (I don't care about the behavior for negative divisors), what's the simplest way to achieve this that is numerically correct for all inputs?
int ifloor(int n, int d)
{
/* returns q such that n = d*q + r where 0 <= r < d
* for all integer n, d where d > 0
*
* d = 0 should have the same behavior as `n/d`
*
* nice-to-have behaviors for d < 0:
* option (a). same as above:
* returns q such that n = d*q + r where 0 <= r < -d
* option (b). rounds towards +infinity:
* returns q such that n = d*q + r where d < r <= 0
*/
}
long lfloor(long n, long d)
{
/* same behavior as ifloor, except for long integers */
}
(update: I want to have a solution both for int and long arithmetic.)
If you can use third-party libraries, Guava has this: IntMath.divide(int, int, RoundingMode.FLOOR) and LongMath.divide(int, int, RoundingMode.FLOOR). (Disclosure: I contribute to Guava.)
If you don't want to use a third-party library for this, you can still look at the implementation.
(I'm doing everything for longs since the answer for ints is the same, just substitute int for every long and Integer for every Long.)
You could just Math.floor a double division result, otherwise...
Original answer:
return n/d - ( ( n % d != 0 ) && ( (n<0) ^ (d<0) ) ? 1 : 0 );
Optimized answer:
public static long lfloordiv( long n, long d ) {
long q = n/d;
if( q*d == n ) return q;
return q - ((n^d) >>> (Long.SIZE-1));
}
(For completeness, using a BigDecimal with a ROUND_FLOOR rounding mode is also an option.)
New edit: Now I'm just trying to see how far it can be optimized for fun. Using Mark's answer the best I have so far is:
public static long lfloordiv2( long n, long d ){
if( d >= 0 ){
n = -n;
d = -d;
}
long tweak = (n >>> (Long.SIZE-1) ) - 1;
return (n + tweak) / d + tweak;
}
(Uses cheaper operations than the above, but slightly longer bytecode (29 vs. 26)).
There's a rather neat formula for this that works when n < 0 and d > 0: take the bitwise complement of n, do the division, and then take the bitwise complement of the result.
int ifloordiv(int n, int d)
{
if (n >= 0)
return n / d;
else
return ~(~n / d);
}
For the remainder, a similar construction works (compatible with ifloordiv in the sense that the usual invariant ifloordiv(n, d) * d + ifloormod(n, d) == n is satisfied) giving a result that's always in the range [0, d).
int ifloormod(int n, int d)
{
if (n >= 0)
return n % d;
else
return d + ~(~n % d);
}
For negative divisors, the formulas aren't quite so neat. Here are expanded versions of ifloordiv and ifloormod that follow your 'nice-to-have' behavior option (b) for negative divisors.
int ifloordiv(int n, int d)
{
if (d >= 0)
return n >= 0 ? n / d : ~(~n / d);
else
return n <= 0 ? n / d : (n - 1) / d - 1;
}
int ifloormod(int n, int d)
{
if (d >= 0)
return n >= 0 ? n % d : d + ~(~n % d);
else
return n <= 0 ? n % d : d + 1 + (n - 1) % d;
}
For d < 0, there's an unavoidable problem case when d == -1 and n is Integer.MIN_VALUE, since then the mathematical result overflows the type. In that case, the formula above returns the wrapped result, just as the usual Java division does. As far as I'm aware, this is the only corner case where we silently get 'wrong' results.
return BigDecimal.valueOf(n).divide(BigDecimal.valueOf(d), RoundingMode.FLOOR).longValue();

Go Golang : Merge Sort Stack Overflow

http://play.golang.org/p/rRccL6YHtQ
I just implement the same code as in CLRS
Pseudocode from CLRS
Merge-Sort(A, p, r)
if p < r
q = [(q+r)/2]
Merge-Sort(A, p, q)
Merge-Sort(A, q+1, r)
Merge(A, p, q, r)
Merge(A, p, q, r)
n_1 = q - p + 1
n_2 = r - q
let L[1 .. n_1 + 1] and R[1 .. n_2 + 1] be new arrays
for i = 1 to n_1
L[i] = A[p+i-1]
for j = 1 to n_2
R[j] = A[q+j]
L[n_1 + 1] = INFINITE
R[n_2 + 1] = INFINITE
i = 1
j = 1
for k = p to r
if L[i] <= R[j]
A[k] = L[i]
i = i + 1
else A[k] = R[j]
j = j + 1
But I am getting the stack overflow in the merge sort.
[9 -13 4 -2 3 1 -10 21 12]
runtime: goroutine stack exceeds 250000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x1b4980, 0x20280)
How do I make this work?
func MergeSort(slice []int, first, last int) {
if len(slice) < 2 {
return
}
if first < last {
mid := len(slice) / 2
MergeSort(slice, first, mid)
MergeSort(slice, mid+1, last)
Merge(slice, first, mid, last)
}
}
thanks a lot!
mid := len(slice) / 2
That's not where the middle should go. The middle is supposed to be halfway between first and last, which define the region of the slice you're sorting, not halfway through the slice. Alternatively, you can slice the slice to make new slices and drop first and last.
You don't seem to be re-slicing the slice you're merge-sorting, so there is no termination of the recursion.
You could either re-slice the slice before recursion, or you can do something like length := last - first (this may have an off-by-one, depending if "last" is the last index or one past the last index) and then go from there.