Progressive loop through pairs of increasing integers - arrays

Suppose one wanted to search for pairs of integers x and y a that satisfy some equation, such as (off the top of my head) 7 x^2 + x y - 3 y^2 = 5
(I know there are quite efficient methods for finding integer solutions to quadratics like that; but this is irrelevant for the purpose of the present question.)
The obvious approach is to use a simple double loop "for x = -max to max; for y = -max to max { blah}" But to allow the search to be stopped and resumed, a more convenient approach, picturing the possible integers of x and y as a square lattice of points in the plane, is to work round a "square spiral" outward from the origin, starting and stopping at (say) the top right corner.
So basically, I am asking for a simple and sound "pseudo-code" for the loops to start and stop this process at points (m, m) and (n, n) respectively.
For extra kudos, if the reader is inclined, I suggest also providing the loops if one of x can be assumed non-negative, or if both can be assumed non-negative. This is probably somewhat easier, especially the second.
I could whump this up myself without much difficulty, but am interested in seeing neat ideas of others.
This would make quite a good "constructive" interview challenge for those dreaded interviewers who like to torture candidates with white boards ;-)

def enumerateIntegerPairs(fromRadius, toRadius):
for radius in range(fromRadius, toRadius + 1):
if radius == 0: yield (0, 0)
for x in range(-radius, radius): yield (x, radius)
for y in range(-radius, radius): yield (radius, -y)
for x in range(-radius, radius): yield (-x, -radius)
for y in range(-radius, radius): yield (-radius, y)

Here is a straightforward implementation (also on ideone):
void turn(int *dr, int *dc) {
int tmp = *dc;
*dc = -*dr;
*dr = tmp;
}
int main(void) {
int N = 3;
int r = 0, c = 0;
int sz = 0;
int dr = 1, dc = 0, cnt = 0;
while (r != N+1 && c != N+1) {
printf("%d %d\n", r, c);
if (cnt == sz) {
turn(&dr, &dc);
cnt = 0;
if (dr == 0 && dc == -1) {
r++;
c++;
sz += 2;
}
}
cnt++;
r += dr;
c += dc;
}
return 0;
}
The key in the implementation is the turn function, that performs the right turn given a pair of {delta-Row, delta-Col}. The rest is straightforward arithmetic.

Related

e^x without math.h

I'm trying to find ex without using math.h. My code gives wrong anwsers when x is bigger or lower than ~±20. I tried to change all double types to long double types, but it gave some trash on input.
My code is:
#include <stdio.h>
double fabs1(double x) {
if(x >= 0){
return x;
} else {
return x*(-1);
}
}
double powerex(double x) {
double a = 1.0, e = a;
for (int n = 1; fabs1(a) > 0.001; ++n) {
a = a * x / n;
e += a;
}
return e;
}
int main(){
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
scanf("%d", &n);
for(int i = 0; i<n; i++) {
double number;
scanf("%lf", &number);
double e = powerex(number);
printf("%0.15g\n", e);
}
return 0;
}
Input:
8
0.0
1.0
-1.0
2.0
-2.0
100.0
-100.0
0.189376476361643
My output:
1
2.71825396825397
0.367857142857143
7.38899470899471
0.135379188712522
2.68811714181613e+043
-2.91375564689153e+025
1.20849374134639
Right output:
1
2.71828182845905
0.367879441171442
7.38905609893065
0.135335283236613
2.68811714181614e+43
3.72007597602084e-44
1.20849583696666
You can see that my answer for e−100 is absolutely incorrect. Why does my code output this? What can I do to improve this algorithm?
When x is negative, the sign of each term alternates. This means each successive sum switches widely in value rather than increasing more gradually when a positive power is used. This means that the loss in precision with successive terms has a large effect on the result.
To handle this, check the sign of x at the start. If it is negative, switch the sign of x to perform the calculation, then when you reach the end of the loop invert the result.
Also, you can reduce the number of iterations by using the following counterintuitive condtion:
e != e + a
On its face, it appears that this should always be true. However, the condition becomes false when the value of a is outside of the precision of the value of e, in which case adding a to e doesn't change the value of e.
double powerex(double x) {
double a = 1.0, e = a;
int invert = x<0;
x = fabs1(x);
for (int n = 1; e != e + a ; ++n) {
a = a * x / n;
e += a;
}
return invert ? 1/e : e;
}
We can optimize a bit more to remove one loop iteration by initializing e with 0 instead of a, and calculating the next term at the bottom of the loop instead of the top:
double powerex(double x) {
double a = 1.0, e = 0;
int invert = x<0;
x = fabs1(x);
for (int n = 1; e != e + a ; ++n) {
e += a;
a = a * x / n;
}
return invert ? 1/e : e;
}
For values of x above one or so, you may consider to handle the integer part separately and compute powers of e by squarings. (E.g. e^9 = ((e²)²)².e takes 4 multiplies)
Indeed, the general term of the Taylor development, x^n/n! only starts to decrease after n>x (you multiply each time by x/k), so the summation takes at least x terms. On another hand, e^n can be computed in at most 2lg(n) multiplies, which is more efficient and more accurate.
So I would advise
to take the fractional part of x and use Taylor,
when the integer part is positive, multiply by e raised to that power,
when the integer part is zero, you are done,
when the integer part is negative, divide by e raised to that power.
You can even spare more by considering quarters: in the worst case (x=1), Taylor requires 18 terms before the last one becomes negligible. If you consider subtracting from x the immediately inferior multiple of 1/4 (and compensate multiplying by precomputed powers of e), the number of terms drops to 12.
E.g. e^0.8 = e^(3/4+0.05) = 2.1170000166126747 . e^0.05

3D Sobel Operator Algorith in C

I'm currently struggling to make a 3D Sobel edge detector in C (which I am quite new to). It's not exactly working as expected (highlighting non-edges within a solid 3D object) and I was hoping someone might see where I've gone wrong. (and sorry for the poor spacing in this post)
First of all, im is the input image which has been copied into tm with a 1 pixel border on each side.
I loop through the image:
for (z = im.zlo; z <= im.zhi; z++) {
for (y = im.ylo; y <= im.yhi; y++) {
for (x = im.xlo; x <= im.xhi; x++) {
I make an array which will house the change in the x, y, and z directions, and loop through a 3x3x3 cube:
int dxdydz[3] = {0, 0, 0};
for (a = -1; a < 2; a++) {
for (b = -1; b < 2; b++) {
for (c = -1; c < 2; c++) {
Now here's the meat, where it gets a bit tricky. I'm weighting my Sobel operator such that if you imagine one 2D surface of the kernel, it would be {{1,2,1},{2,4,2},{1,2,1}}. In other words, the weight of a kernel pixel is related to its 4-connected nearness to the center pixel.
To accomplish this, I define e as 3 - (|a| + |b| + |c|), so that it is either 0, 1, or 2. The kernel will be weighted by 3^e at each pixel.
The sign of the kernel pixel will just be determined by the sign of a, b, or c.
int e = 3 - (abs(a) + abs(b) + abs(c));
Now I loop through a, b, and c by packaging them into an array and looping from 0-1-2. When a for example is 0, we don't want to add any values to x, so we exclude that with an if statement (8 levels deep!).
int abc[3] = {a, b, c};
for (i = 0; i < 3; i++) {
if (abc[i] != 0) {
The value to add should just be the image value at that pixel multiplied by the kernel value at that pixel. abc[i] is just -1 or 1, and (int)pow(3, e) is the nearness-to-center weight.
dxdydz[i] += abc[i]*(int)pow(3, e)*tm.u[z+a][y+b][x+c];
}
}
}
}
}
Lastly take the sqrt of the sum of the squared changes in x, y, and z.
int mag2 = 0;
for (i = 0; i < 3; i++) {
mag2 += (int)pow(dxdydz[i], 2);
}
im.u[z][y][x] = (int)sqrt(mag2);
}
}
}
Of course I could just loop through the image and multiply 3x3x3 cubes by the 3D kernels:
int kx[3][3][3] = {{{-1,-2,-1},{0,0,0},{1,2,1}},
{{-2,-4,-2},{0,0,0},{2,4,2}},
{{-1,-2,-1},{0,0,0},{1,2,1}}};
int ky[3][3][3] = {{{-1,-2,-1},{-2,-4,-2},{-1,-2,-1}},
{{0,0,0},{0,0,0},{0,0,0}},
{{1,2,1},{2,4,2},{1,2,1}}};
int kz[3][3][3] = {{{-1,0,1},{-2,0,2},{-1,0,1}},
{{-2,0,2},{-4,0,4},{-2,0,2}},
{{-1,0,1},{-1,0,1},{-1,0,1}}};
But I think the loop approach is a lot sexier.

Fast implementation binary exponentiation implementation in OpenCL

I've been trying to design a fast binary exponentiation implementation in OpenCL. My current implementation is very similar to the one in this book about pi.
// Returns 16^n mod ak
inline double expm (long n, double ak)
{
double r = 16.0;
long nt;
if (ak == 1) return 0.;
if (n == 0) return 1;
if (n == 1) return fmod(16.0, ak);
for (nt=1; nt <= n; nt <<=1);
nt >>= 2;
do
{
r = fmod(r*r, ak);
if ((n & nt) != 0)
r = fmod(16.0*r, ak);
nt >>= 1;
} while (nt != 0);
return r;
}
Is there room for improvement? Right now my program is spending the vast majority of it's time in this function.
My first thought is to vectorize it, for a potential speed up of ~1.6x. This uses 5 multiplies per loop compared to 2 multiplies in the original, but with approximately a quarter the number of loops for sufficiently large N. Converting all the doubles to longs, and swapping out the fmods for %s may provide some speed up depending on the exact GPU used and whatever.
inline double expm(long n, double ak) {
double4 r = (1.0, 1.0, 1.0, 1.0);
long4 ns = n & (0x1111111111111111, 0x2222222222222222, 0x4444444444444444,
0x8888888888888888);
long nt;
if(ak == 1) return 0.;
for(nt=15; nt<n; nt<<=4); //This can probably be vectorized somehow as well.
do {
double4 tmp = r*r;
tmp = tmp*tmp;
tmp = tmp*tmp;
r = fmod(tmp*tmp, ak); //Raise it to the 16th power,
//same as multiplying the exponent
//(of the result) by 16, same as
//bitshifting the exponent to the right 4 bits.
r = select(fmod(r*(16.0,256.0,65536.0, 4294967296.0), ak), r, (ns & nt) - 1);
nt >>= 4;
} while(nt != 0); //Process n four bits at a time.
return fmod(r.x*r.y*r.z*r.w, ak); //And then combine all of them.
}
Edit: I'm pretty sure it works now.
The loop to extract nt = log2(n); can be replaced by
if (n & 1) ...; n >>= 1;
in the do-while loop.
Given that initially r = 16;, fmod(r*r, ak) vs fmod(16*r,ak) can be easily delayed to calculate the modulo only every Nth iteration or so -- Loop unrolling?
Also why fmod?

C Language - General algorithm to read a square matrix, based on the square number of it's side?

So we're reading a matrix and saving it in an array sequentially. We read the matrix from a starting [x,y] point which is provided. Here's an example of some code I wrote to get the values of [x-1,y] [x+1,y] [x,y-1] [x,y+1], which is a cross.
for(i = 0, n = -1, m = 0, array_pos = 0; i < 4; i++, n++, array_pos++) {
if(x+n < filter_matrix.src.columns && x+n >= 0 )
if(y+m < filter_matrix.src.lines && y+m >= 0){
for(k = 0; k < numpixels; k++) {
arrayToProcess[array_pos].rgb[h] = filter_matrix.src.points[x+n][y+m].rgb[h];
}
}
m = n;
m++;
}
(The if's are meant to avoid reading null positions, since it's an image we're reading the origin pixel can be located in a corner. Not relevant to the issue here.)
Now is there a similar generic algorithm which can read ALL the elements around as a square (not just a cross) based on a single parameter, which is the size of the square's side squared?
If it helps, the only values we're dealing with are 9, 25 and 49 (a 3x3 5x5 and 7x7 square).
Here is a generalized code for reading the square centered at (x,y) of size n
int startx = x-n/2;
int starty = y-n/2;
for(int u=0;u<n;u++) {
for(int v=0;v<n;v++) {
int i = startx + u;
int j = starty + v;
if(i>=0 && j>=0 && i<N && j<M) {
printf(Matrix[i][j]);
}
}
}
Explanation: Start from top left value which is (x - n/2, y-n/2) now consider that you are read a normal square matrix from where i and j are indices of Matrix[i][j]. So we just added startx & starty to shift the matrix at (0,0) to (x-n/2,y-n/2).
Given:
static inline int min(int x, int y) { return (x < y) ? x : y; }
static inline int max(int x, int y) { return (x > y) ? x : y; }
or equivalent macros, and given that:
the x-coordinates range from 0 to x_max (inclusive),
the y-coordinates range from 0 to y_max (inclusive),
the centre of the square (x,y) is within the bounds,
the square you are creating has sides of (2 * size + 1) (so size is 1, 2, or 3 for the 3x3, 5x5, and 7x7 cases; or if you prefer to have sq_side = one of 3, 5, 7, then size = sq_side / 2),
the integer types are all signed (so x - size can produce a negative value; if they're unsigned, you will get the wrong result using the expressions shown),
then you can ensure that you are within bounds by setting:
x_lo = max(x - size, 0);
x_hi = min(x + size, x_max);
y_lo = max(y - size, 0);
y_hi = min(y + size, y_max);
for (x_pos = x_lo; x_pos <= x_hi; x_pos++)
{
for (y_pos = y_lo; y_pos <= y_hi; y_pos++)
{
// Process the data at array[x_pos][y_pos]
}
}
Basically, the initial assignments determine the bounds of the the array from [x-size][y-size] to [x+size][y+size], but bounded by 0 on the low side and the maximum sizes on the high end. Then scan over the relevant rectangular (usually square) sub-section of the matrix. Note that this determines the valid ranges once, outside the loops, rather than repeatedly within the loops.
If the integer types are signed, you have ensure you never try to create a negative number during subtraction. The expressions could be rewritten as:
x_lo = x - min(x, size);
x_hi = min(x + size, x_max);
y_lo = y - min(y, size);
y_hi = min(y + size, y_max);
which isn't as symmetric but only uses the min function.
Given the coordinates (x,y), you first need to find the surrounding elements. You can do that with a double for loop, like this:
for (int i = x-1; i <= x+1; i++) {
for (int j = y-1; j <= y+1; j++) {
int elem = square[i][j];
}
}
Now you just need to do a bit of work to make sure that 0 <= i,j < n, where n is the length of a side;
I don't know whether the (X,Y) in your code is the center of the square. I assume it is.
If the side of the square is odd. generate the coordinates of the points on the square. I assume the center is (0,0). Then the points on the squares are
(-side/2, [-side/2,side/2 - 1]); ([-side/2 + 1,side/2], -side/2); (side/2,[side/2 - 1,-side/2]);([side/2 - 1, side/2],-side/2);
side is the length of the square
make use of this:
while(int i<=0 && int j<=0)
for (i = x-1; i <= x+1; i++) {
for (j = y-1; j <= y+1; j++) {
int elem = square[i][j];
}
}
}

Relatively prime check?

Ok so relatively prime means that two numbers have no common factors greater than 1. It can also be viewed as two numbers that have gcd = 1.
So along those lines, this is the code i wrote to find two relatively prime numbers e,z :
for(e = 0,flag=0; (flag==1); e++){
if( gcd( e, z ) == 1){ // z in this example is 60
flag = 1;
}
}
printf("e = %d\n",e);
and the gcd function is defined as :
int gcd(int i, int x){
if(x % i == 0) return( i );
return( gcd( x % i, x ) );
}
when I set z = 60, the e I get is e= 0 ... Actually I keep getting the same e with which I initialize the for loop
What am I doing wrong? Is there any other way of finding if two numbers are relatively prime?
EDIT:
Ok as per the suggestion from minitech here is the modified code:
for(e = 2,flag=0; !flag; e++){
if( gcd( e, z ) == 1){
flag = 1;
}
}
now when I set my z=60 , my e is coming out to be e = 60 which is again wrong. Correct answer should be e = 7
You shouldn’t start at zero
Your flag condition should be !flag
After fixing that, you will always get 1, because it’s relatively prime to everything. Try starting at z - 1 and decrementing if you want the biggest one. You should also just break; instead of keeping a flag.
This is a little fragile, since it can't handle a zero argument; e.g.,
gcd(z, z) = gcd(z, 0) = gcd(0, z) = |z|.
I'd go with something like:
unsigned gcd (unsigned u, unsigned v)
{
unsigned t;
for (; (t = v) != 0; u = t)
v = u % v;
return u;
}
I use unsigned types, because there's no reason to use negative arguments - they don't affect the result of a gcd, which is always non-negative.

Resources