I set up an array like this.
img = % A GRAY-SCALE IMAGE
r = 20;
corners = randi( [1080, 1020], 100, 2);
d = r * 2 + 1;
squares = zeros(size(corners, 1), d, d);
w = corners(:, 1);
h = corners(:, 2);
for i = 1:size(corners, 1)
sq = img(max(w(i) - r, 0) : min(w(i) + r, size(img, 1)), ...
max(h(i) - r, 0) : min(h(i) + r, size(img, 2)));
squares(i, :, :) = (sq - mean(sq(:))) / std(sq(:));
end
When I try to run this code, I get an error message saying "Assignment has fewer non-singleton rhs dimensions than non-singleton subscripts". I'm not sure what this means because when I print out size(squares(i, :, :)) and size(sq) I get 1 41 41 and 41 41 respectively. I'm not sure what's wrong or how to fix it. Help?
Related
static inline bool is_divisible(uint32_t n, uint64_t M) {
return n * M <= M - 1;
}
static uint64_t M3 = UINT64_C(0xFFFFFFFFFFFFFFFF) / 3 + 1;
....
uint8_t div3 = is_divisible(17, M3);
As mention in title, this function can determine whether n is divisible by 3.
The only thing I figure out is that M is same as ceil((1<<64)/d) which d is 3.
Are there anyone call explain why is_divisible work? thanks!
Divide n by 3 to find quotient q and remainder r, allowing us represent n as n = 3q + r, where 0 ≤ r < 3.
Intuitively, multiple 3q + r by (264−1)/3 + 1 causes the q portion to vanish because it wraps modulo 264, leaving the remainder portion to be in one of three segments of [0, 264) depending on the value of r. The comparison with M3 determines whether it is in the first segment, meaning r is zero. A proof follows.
Note that M3 is (264−1)/3 + 1.
Then n•M3 = (3q + r)•((264−1)/3 + 1) = q•(264−1)+3q+r•((264−1)/3 + 1) = q•264+2q+r•((264−1)/3 + 1).
When this is evaluated with uint64_t arithmetic, the q•264 term vanishes due to wrapping modulo 264, so the computed result is
2q+r•((264−1)/3 + 1).
Suppose n is a multiple of 3. Then r = 0. Since n is a uint32_t value, q < 232, so 2q+r•((264−1)/3 + 1) = 2q < 233 < M3.
Suppose n is not a multiple of 3. Then r = 1 or r = 2. If r = 1, r•((264−1)/3 + 1) = (264−1)/3 + 1 > M3−1. And, of course, if r = 2, r•((264−1)/3 + 1) is even greater and also exceeds M3−1. However, we need to be concerned about wrapping in uint64_t arithmetic. Again, since q < 232, we have, for r = 2, 2q+r•((264−1)/3 + 1) < 2•232 + 2•((264−1)/3 + 1) = 233 + 2/3•264 − 2/3 + 2 = 264 − 1/3•264 + 233 + 4/3, which is clearly less than 264, so no wrapping occurs.
So, I have to make a work for college and it consists in creating an algorithm.
The algorithm must find couples of numbers which satisfy a certain condition, which is: the sum from 1 to n (exlusive) results the same as the sum from n+1 to m (inclusive).
At the final, the algorithm must give at least 15 couples.
The first couple is 6 and 8, because from 1 to n (exclusive) (6) is 1+2+3+4+5 = 15 and from n+1 to m is 8+7 = 15.
The algorithm I created is the following one:
int main() {
int count = 0;
unsigned int before = 0;
unsigned int after = 0;
unsigned int n = 1;
unsigned int m = 0;
do {
before += n - 1;
after = n + 1;
for (m = after + 1; after < before; m++) {
after += m;
}
if (before == after) {
printf("%d\t%d\n", n, (m - 1));
count++;
}
n++;
} while (count < 15);
}
This is actually OK, but some of the output are not correct, and its also crap, in terms of complexity, and since I am studying Complexity of Algorithms, it would be good to find some algorithm better than this one.
I also tried doing it in Java, but using int is not good for this problem and using long, it takes hours and hours to compute.
The numbers I have found so far:
6 and 8
35 and 49
204 and 288
1189 and 1681
6930 and 9800
40391 and 57121
The following ones may be incorrect:
100469 and 107694
115619 and 134705
121501 and 144689
740802 and 745928
1250970 and 1251592
2096128 and 2097152
2100223 and 2101246
4196352 and 8388608
18912301 and 18912497
Your results are incorrect beyond the first 6: the range of type unsigned int is insufficient to store the sums. You should use type unsigned long long for before and after.
Furthermore, your algorithm becomes very slow for large values because you recompute after from scratch for each new value of before, with a time complexity of O(N2). You can keep 2 running sums in parallel and reduce the complexity to quasi-linear.
Last but not least, there are only 12 solutions below UINT32_MAX, so type unsigned long long, which is guaranteed to have at least 64 value bits is required for n and m as well. To avoid incorrect results, overflow should be tested when updating after.
Further tests show that the sums after and before exceed 64 bits for values of m around 8589934591. A solution is to subtract 262 from both before and after when they reach 263. With this modification, the program can keep searching for larger values of n and m much beyond 32-bits.
Here is an improved version:
#include <stdio.h>
int main() {
int count = 0;
unsigned long long n = 1;
unsigned long long m = 2;
unsigned long long before = 0;
unsigned long long after = 2;
for (;;) {
if (before < after) {
before += n;
n++;
after -= n;
} else {
m++;
/* reduce values to prevent overflow */
if (after > 0x8000000000000000) {
after -= 0x4000000000000000;
before -= 0x4000000000000000;
}
after += m;
while (before > after) {
after += n;
n--;
before -= n;
}
}
if (before == after) {
printf("%llu\t%llu\n", n, m);
count++;
if (count == 15)
break;
}
}
printf("%d solutions up to %llu\n", count, m);
return 0;
}
Output (running time 30 minutes):
6 8
35 49
204 288
1189 1681
6930 9800
40391 57121
235416 332928
1372105 1940449
7997214 11309768
46611179 65918161
271669860 384199200
1583407981 2239277041
9228778026 13051463048
53789260175 76069501249
313506783024 443365544448
15 solutions up to 443365544448
Your initial brute force program as posted above generates plenty of data for you to analyze. The people in the question's comments recommended the "sum of an arithmetic series" formula instead of your repeated addition, but the fact is that it still would run slow. It's surely an improvement, but it's still not good enough if you want something usable.
Believe it or not, there are some patterns to the values of n and m, which will require some math to explain. I'll be using the functions n(i), m(i), and d(i) = m(i) - n(i) to represent the values of n, m, and the difference between them, respectively, during iteration i.
You found the first six couples:
i n(i) m(i) d(i)
== ====== ====== ======
1 6 8 2
2 35 49 14
3 204 288 84
4 1189 1681 492
5 6930 9800 2870
6 40391 57121 16730
Notice that 6+8 = 14, 35+49 = 84, 204+288 = 492, etc. It so happens that, in the general case, d(i+1) = m(i) + n(i) (e.g. d(2) = m(1) + n(1) = 6 + 8 = 14).
So now we know the following:
d(7)
= n(6) + m(6)
= 40391 + 57121
= 97512
# m(i) = n(i) + d(i)
m(7) = n(7) + 97512
Another way of looking at it since m(i) = n(i) + d(i) is d(i+1) = d(i) + 2n(i):
d(7)
= n(6) + d(6) + n(6)
= d(6) + 2n(6)
= 16730 + 2(40391)
= 97512
d(i) also happens to be useful for computing n(i+1):
n(i+1) = 2d(i+1) + n(i) + 1
n(7) = 2d(7) + n(6) + 1
= 2(97512) + 40391 + 1
= 235416
From there, it's easy to determine things:
i n(i) m(i) d(i)
== ====== ====== ======
1 6 2 8
2 35 14 49
3 204 84 288
4 1189 492 1681
5 6930 2870 9800
6 40391 16370 57121
7 235416 332928 97512
But what about a starting condition? We need a way to find 6 in the first place, and that starting case can be computed by working backward and using substitution:
n(1) = 2d(1) + n(0) + 1
6 = 2(2) + n(0) + 1
5 = 4 + n(0)
1 = n(0)
d(1) = d(0) + 2n(0)
2 = d(0) + 2(1)
2 = d(0) + 2
0 = d(0)
m(0) = n(0) + d(0)
= 1 + 0
= 1
Note that n(0) = m(0) (1 = 1), but it is not a couple. For a pair of numbers to be a couple, the numbers must not be the same.
All that's left is to compute the sum. Since the integers from 1 to n-1 (i.e. 1 to n, excluding n) form an arithmetic series and the series starts at 1, you can use the formula
n(n - 1)
S(n) = --------
2
Below is a program that uses all of this information. You'll notice I'm using a multiplication function mul in place of the multiplication operator. The function's result is used to end the loop prematurely when an unsigned overflow (i.e. wraparound) is encountered. There are probably better ways to detect the wraparound behavior, and the algorithm could be better designed, but it works.
#include <errno.h>
#include <limits.h>
#include <stdio.h>
typedef unsigned long long uval_t;
/*
* Uses a version of the "FOIL method" to multiply two numbers.
* If overflow occurs, 0 is returned, and errno is ERANGE.
* Otherwise, no overflow occurs, and the product m*n is returned.
*/
uval_t mul(uval_t m, uval_t n)
{
/*
* Shift amount is half the number of bits in uval_t.
* This allows us to work with the upper and lower halves.
* If the upper half of F is not zero, overflow occurs and zero is returned.
* If the upper half of (O+I << half_shift) + L is not zero,
* overflow occurs and zero is returned.
* Otherwise, the returned value is the mathematically accurate result of m*n.
*/
#define half_shift ((sizeof (uval_t) * CHAR_BIT) >> 1)
#define rsh(v) ((v) >> half_shift)
#define lsh(v) ((v) << half_shift)
uval_t a[2], b[2];
uval_t f, o, i, l;
a[0] = rsh(m);
a[1] = m & ~lsh(a[0]);
b[0] = rsh(n);
b[1] = n & ~lsh(b[0]);
f = a[0] * b[0];
if (f != 0)
{
errno = ERANGE;
return 0;
}
o = a[0] * b[1];
i = a[1] * b[0];
l = a[1] * b[1];
if (rsh(o+i + rsh(l)) != 0)
{
errno = ERANGE;
return 0;
}
return lsh(o+i) + l;
}
int main(void)
{
int i;
uval_t n = 1, d = 0;
uval_t sum = 0;
#define MAX 15
for (i = 1; i <= MAX; i++)
{
d += n * 2;
n += d * 2 + 1;
sum = mul(n, n - 1) / 2;
if (sum == 0)
break;
printf("%2d\t%20llu\t%20llu\t%20llu\n", i, n, n+d, sum);
}
return 0;
}
This yields 12 lines of output, the last being this one:
12 1583407981 2239277041 1253590416355544190
Of course, if you don't care about the sums, then you can just avoid computing them entirely, and you can find all 15 couples just fine without even needing to check for overflow of a 64-bit type.
To go further with the sums, you have a few options, in order of most to least recommended:
use a "bignum" library such as GNU MP, which is similar to Java's java.math.BigInteger class and which has its own printf-like function for displaying values; if you're on Linux, it may already be available
use your compiler's 128-bit type, assuming it has one available, and create your own printing function for it if necessary
create your own "big integer" type and the associated necessary addition, subtraction, multiplication, division, etc. printing functions for it; a way that allows for easy printing is that it could just be two unsigned long long values glued together with one representing the lower 19 decimal digits (i.e. the max value for it would be 999 9999 9999 9999 9999), and the other representing the upper 19 digits for a total of 38 digits, which is 1038-1 or 127 bits
The fact that the full 15 sums required don't fit in 64 bits, however, makes me concerned that the question was perhaps worded badly and wanted something different from what you wrote.
Edit
To prove this works, we must first establish some rules:
For any values n and m, 0 ≤ n < m must be true, meaning n == m is forbidden (else we don't have a couple, a.k.a. "ordered pair").
n and m must both be integers.
With that out of the way, consider an algorithm for computing the sum of an arithmetic series starting at a and ending at, and including, b with a difference of +1 between each successive term:
(b - a + 1)(b + a)
S(a, b) = ------------------
2
b² - a² + b + a
= ---------------
2
b(1 + b) + a(1 - a)
= -------------------
2
If such a series begins at a=1, you can derive a simpler formula:
b(b + 1)
S(b) = --------
2
Applying this to your problem, you want to know how to find values such that the following is true:
S(n-1) = S(n+1, m)
After applying the arguments, the result looks like this:
(n-1)n m(1 + m) + (n+1)[1 - (n+1)]
------ = ---------------------------
2 2
(n-1)n = m(1 + m) + (n+1)(1 - n - 1)
n² - n = m² + m + (n+1)(-n)
n² - n = m² + m - n² - n
2n² = m² + m
While not important for my purposes, it's perhaps worth noting that m² + m can be rewritten as m(m+1), and the 2n² signifies that one or both of m and m+1 must be divisible by 2. In addition, one must be a perfect square while the other must be twice a perfect square due to the requirement that at least one expression must be divisible by 2. In other words, 2n² = m(m+1) = 2x²y². You can find another equally valid solution using x and y to generate the values of n and m, but I won't demonstrate that here.
Given the equations for n(i+1), m(i+1), and d(i+1):
d(i+1) = d(i) + 2n(i)
= m(i) + n(i)
n(i+1) = 2d(i+1) + n(i) + 1
= 2m(i) + 3n(i) + 1
m(i+1) = d(i+1) + n(i+1)
= 3m(i) + 4n(i) + 1
And the starting conditions:
n(0) = 1
d(0) = 0
m(0) = 1
We can determine whether they actually work by substituting i+2 in place of i in all cases and finding whether we end up with the same equation. Assuming f(n(i)) = 2n²(i) and g(m(i)) = m(i) ⋅ (m(i) + 1), the equation f(n(i+2)) = g(m(i+2)) reduces to f(n(i)) = g(m(i)), proving the equations work for any couple:
f(n(i+2))
= g(m(i+2))
f(2m(i+1) + 3n(i+1) + 1)
= g((3m(i+1) + 4n(i+1) + 1))
2 ⋅ (12m(i) + 17n(i) + 6)²
= (17m(i) + 24n(i) + 8) ⋅ (17m(i) + 24n(i) + 8 + 1)
2 ⋅ (144m²(i) + 408m(i)⋅n(i) + 144m(i) + 289n²(i) + 204n(i) + 36)
= 289m²(i) + 816m(i)⋅n(i) + 289m(i) + 576n²(i) + 408n(i) + 72
288m²(i) + 816m(i)⋅n(i) + 288m(i) + 578n²(i) + 408n(i) + 72
= 289m²(i) + 816m(i)⋅n(i) + 289m(i) + 576n²(i) + 408n(i) + 72
2n²(i)
= m²(i) + m(i)
f(n(i))
= g(m(i))
If you're lost toward the end, I simply subtracted 288m²(i) + 816m(i)⋅n(i) + 288m(i) + 576n²(i) + 408n(i) + 72 from both sides of the equation, yielding 2n²(i) = m²(i) + m(i).
I need to find the smallest number of steps it takes to get between two points in a grid. If you are positioned at the center, and you can only move in 8 directions to the integer points surrounding you, then what's the least number of steps to take to get to a destination point?
I have a solution for this, but it is massively ugly and I'm honestly a bit ashamed of it:
/**
* #details Each point in the graph is a linear combination of these vectors:
*
* [x] = a[0] + b[1] + c[1] + d[ 1]
* [y] [1] [1] [0] [-1]
*
* EQ1: c + b + d == x
* EQ2: a + b - d == y
*
* Any path can be simplified to involve at most two of these variables, so we
* can solve the linear equations above with the knowledge that at least two of
* a, b, c, and d are 0. The sum of the absolute value of the coefficients is
* the number of steps taken in the grid.
*/
unsigned min_distance(point_t start, point_t goal)
{
int a, b, c, d;
int swap, steps;
int x, y;
x = goal.x - start.x;
y = goal.y - start.y;
/* Possible simple shortcuts */
if (x == 0 || y == 0) {
steps = abs(x) + abs(y);
} else if (abs(x) == abs(y)) {
steps = abs(y);
} else {
b = x, a = y - b;
steps = abs(a) + abs(b);
c = x, a = y;
swap = abs(a) + abs(c);
if (steps > swap)
steps = swap;
d = x, a = y + d;
swap = abs(a) + abs(d);
if (steps > swap)
steps = swap;
b = y, c = x - b;
swap = abs(b) + abs(c);
if (steps > swap)
steps = swap;
b = (x + y) / 2, d = b - y;
swap = abs(b) + abs(d);
if ((x + y) % 2 == 0 && steps > swap)
steps = swap;
d = -y, c = x - d;
swap = abs(c) + abs(d);
if (steps > swap)
steps = swap;
}
return steps;
}
The comment at the top explains the actual algorithm: represent each valid step as a column vector in a matrix, then find the smallest solution to the resulting system of linear equations.
In this case I saw the best answer would use at most two variables, and solved the equation six times by setting different combinations of the variables to 0. That's too specific! I want to be able to change the rules about which steps are valid and still be able to find the min distance.
EDIT: I realize this is a very poor simple example of what I'm trying to do, because of how easy it is to simplify the problem in this case. The goal is to calculate the number of steps given arbitrary stepping rules. If it the allowed steps instead looked like this then I'd start with a different matrix ([0 2 3 4 x; 1 2 0 -4 y]) and find the least solution to a different system of equations (2b + 3c + 4d = x, a + 2b - 4d = y). I'm actually trying to write a procedure that can work with any set of vectors to find the minimum number of steps.
...Any advice or criticism?
alright. I have the Euclidean division like this : a = b * q + r
I know that to get r, I can do the modulo : a % b
but how do I get q ? // doesn't seem to work.
Using Euclidean division
If a = 7 and b = 3, then q = 2 and r = 1, since 7 = 3 × 2 + 1.
If a = 7 and b = −3, then q = −2 and r = 1, since 7 = −3 × (−2) + 1.
If a = −7 and b = 3, then q = −3 and r = 2, since −7 = 3 × (−3) + 2.
If a = −7 and b = −3, then q = 3 and r = 2, since −7 = −3 × 3 + 2.
Likely a more simple solution is available.
int Ediv(int a, int b) {
printf("a:%2d / b:%2d = ", a,b);
int r = a % b;
if (r < 0) r += abs(b);
printf("r:%2d ", r);
return (a - r) / b;
}
void Etest() {
printf("q:%2d\n", Ediv(7,3));
printf("q:%2d\n", Ediv(7,-3));
printf("q:%2d\n", Ediv(-7,3));
printf("q:%2d\n", Ediv(-7,-3));
}
a: 7 / b: 3 = r: 1 q: 2
a: 7 / b:-3 = r: 1 q:-2
a:-7 / b: 3 = r: 2 q:-3
a:-7 / b:-3 = r: 2 q: 3
OP asserts "I know that to get r, I can do the modulo : a % b". This fails when a is negative.
Further, % is the "remainder operator". In C, the difference between Euclidean remainder and modulo occurs when a is negative. Remainder calculation for the modulo operation
If a and b are integers, just use integer division, /.
chux's answer is a good one, as it's the one that correctly understands the question (unlike the accepted one). Daan Leijen's Division and Modulus for Computer Scientists also provides an algorithm with proof:
/* Euclidean quotient */
long quoE(long numer, long denom) {
/* The C99 and C++11 languages define both of these as truncating. */
long q = numer / denom;
long r = numer % denom;
if (r < 0) {
if (denom > 0)
q = q - 1; // r = r + denom;
else {
q = q + 1; // r = r - denom;
}
return q;
}
This one is trivially equivalent to chux's algorithm. It looks a bit more verbose, but it might take one fewer div instruction on x86, as the instruction performs a "divmod" -- returning q and r at the same time.
Take an example:
7 = 3*2 + 1
2 (q) can be obtained by 7/3, i.e, a/b = q.
I am trying to find a function which takes the position of a cell(x,y) in the matrix(MXN) and gives its position(1<=p<=M*N) in the spiral order traversal of the matrix . For example :
for M = 3, N = 3 , and matrix :
[1,2,3]
[4,5,6]
[7,8,9]
Spiral Order Traversal yields : { 1,2,3,6,9,8,7,4,5 } , so if the function is denoted by F(x,y) , then :
F(1,1) = 1 , F(1,2) = 2, F(1,3) = 3, F(2,3) = 6 , .. , and so on.
So basically I need a closed form formula which for a given M,N, and a position (x,y) , yields the position of that cell in the spiral order traversal.
Let's start with finding in which "round" the cell is. That is, how often did the spiral go fully around before hitting this cell:
int n = min(x, y, M - x - 1, N - y - 1);
The first full round consists of 2*M + N) - 4 cells, the next one of 2*(M + N) - 12 cells, and so on (I hope you believe me in this). More general, round i consists of 2*(M + N - 2) - 8*i cells.
So how many cells are in the first n rounds? Just sum the value just found:
sum(0 <= i < n : 2*(M + N - 2) - 8*i) = 2*n*(M + N - 2) - 8 * sum(0 <= i < n : i)
= 2*n*(M + N - 2) - 8 * n * (n - 1) / 2
= 2*n*(M + N - 2*n)
We can already add this value to the index:
int index = 2 * n * (M + N - 2 * n);
Now we just need to check where in the current round the cell is:
if (n == y) {
// top of this round
index += x - n;
} else {
// add full top of this round
index += M - 2 * n;
if (n == M - x - 1) {
// right side of this round
index += y - (n + 1);
} else {
// add full right side of this round
index += N - 2 * n - 1;
if (n == N - y - 1) {
// bottom of this round
index += N - x - 1 - (n + 1);
} else {
// add full bottom of this round
index += M - 2 * n - 1;
// left side of this round
index += M - y - 1 - (n+1);
}
}
}
I called the method spiral(M, N, x, y) and ran it as follows:
System.out.println(spiral(3, 3, 0, 0));
System.out.println(spiral(3, 3, 1, 0));
System.out.println(spiral(3, 3, 2, 0));
System.out.println(spiral(3, 3, 2, 1));
System.out.println(spiral(3, 3, 2, 2));
System.out.println(spiral(3, 3, 1, 2));
System.out.println(spiral(3, 3, 0, 2));
System.out.println(spiral(3, 3, 0, 1));
System.out.println(spiral(3, 3, 1, 1));
Which results in
0
1
2
3
4
5
6
7
8
Okay, I thought of a solution. I didn't write any code yet to test it out, but maybe later if I get home after work I can test it out to be 100% sure.
The first thing you need to do in algorithm is to figure out in which quarter is your position located. For instance in your matrix the center of the matrix isn't in any quarter, but you can always tell on which axis the point is. The general idea is to figure out how far from the side is the point, so how many FULL circuits should it take to get to the point we are looking for.
After we figure out how far from the side we are (it should be easy taking the x and y and the quarter we are in and the size of the matrix) we can use this formula to count the number of positions used in traversal to create these circuits. (n is a distance from the side)
sum = 2n * (M - 2n + N)
If we have the number of positions used to get to the circuit on which is the point we are looking for now the only thing is to figure out how far from this point we are on the circuit. I think it should be easily countable with the knowledge in which quarter we are located.