Related
I'm trying to write a convolution function in C for my computer vision study.
In this function, every pixel in the convolved image is a sum of product of original image and filter kernel like in this image and this gif.
In the code below pixel values are float. get_pixel() function gets the pixel value at given indexes. set_pixel() function sets the value to given indexes.
image convolve(image im, image filter) {
// imx, imy, imc: indexes of image pixels
// fix, fiy: indexes of filter pixels
// rx, ry: relative indexes of pixels
image convolved_img = make_image(im.w, im.h, im.c); // image with same dimensions
float value = 0; // pixel value
int oxo = floor(filter.w / 2); // half of the kernel width
int xox = floor(filter.h / 2); // half of the kernel height
// Convolution Loop
for(int imc = 0; imc < im.c; imc++) { // for every channel
for(int imx = 0; imx < im.w; imx++) {
for(int imy = 0; imy < im.h; imy++) { // for every pixel
value = 0;
for(int fix = 0; fix < filter.w; fix++) {
for(int fiy = 0; fiy < filter.h; fiy++) {
int rx = imx - oxo + fix;
int ry = imy - xox + fiy;
value += get_pixel(filter, fix, fiy, 0) * get_pixel(im, rx, ry, imc);
}
}
set_pixel(convolved_img, imx, imy, imc, value);
}
}
}
return convolved_img;
}
I'm getting segmentation fault (core dumped) error. After debugging I realized its because of line:
value += get_pixel(filter, fix, fiy, 0) * get_pixel(im, rx, ry, imc);
When I gave fixed values of rx and ry, the program executes successfully. Inside the loop I printed the values of imx, imy, fix, fiy, rx, ry and everything works until a portion of the image has processed; after uncertain time of loop then program crushes without any reason.
I'm sure that it cannot be a index bounds related because I truncated indexes inside get_pixel() function below which I get stored value from a long array of floats.
float get_pixel(image im, int x, int y, int c) {
if(x > im.w) {x = im.w;}
else if(y > im.h) {y = im.h;}
else if(c > im.c) {c = im.c;}
else if(x < 0) {x = 0;}
else if(y < 0) {y = 0;}
else if(c < 0) {c = 0;}
int index = (c * (im.h * im.w)) + (y * im.w) + x;
return im.data[index];
}
Here is my thought about this operation as pseudo-code:
create convolved_image with same dimensions
for every pixel (imx, imy) in image {
float value = 0;
for every pixel (fix, fiy) in filter {
// calculate relative pixel coordinates
int rx = imx - (filter / 2) + fix;
int ry = imy - (filter / 2) + fiy;
value += filter(fix, fiy) * image(rx, ry);
}
set pixel of convolved_image to value
}
Am I missing something? What is the fault in my approach? Or is there a better way for this operation?
This is clearly an out of bounds access:
for(int fix = 0; fix < filter.w; fix++) {
for(int fiy = 0; fiy < filter.h; fiy++) {
int rx = imx - oxo + fix;
int ry = imy - xox + fiy;
value += get_pixel(filter, fix, fiy, 0) * get_pixel(im, rx, ry, imc);
}
}
With imx going up to im.x and fix going up to 2*oxo you are clearly larger than im.x. Same for imy.
You try to limit the range but that is not correct:
float get_pixel(image im, int x, int y, int c) {
if(x > im.w) {x = im.w;}
else if(y > im.h) {y = im.h;}
else if(c > im.c) {c = im.c;}
else if(x < 0) {x = 0;}
else if(y < 0) {y = 0;}
else if(c < 0) {c = 0;}
int index = (c * (im.h * im.w)) + (y * im.w) + x;
return im.data[index];
}
You forgot that all parameters can be wrong. You stop after first.
Also you limit to size+1 which also is wrong.
Change like this:
float get_pixel(image im, int x, int y, int c) {
if(x >= im.w) {x = im.w-1;}
else if(x < 0) {x = 0;}
if(y >= im.h) {y = im.h-1;}
else if(y < 0) {y = 0;}
if(c >= im.c) {c = im.c-1;}
else if(c < 0) {c = 0;}
int index = (c * (im.h * im.w)) + (y * im.w) + x;
return im.data[index];
}
I want to make a C program compatible for DEV-C++ 4.9.9.2 to find integer triplets (x,y,z) such that for any integer n the equation n^x + n^y = n^z holds where n is any integer in the range [a,b]. The c program would have an input of only a and b and find such possible triplets.
The code that I wrote isn't working. What's the error in it?
for (n = a ; n <= b ; n++) {
for (x = a ; x < b ; x++) {
for (y = a ; y < b ; y++) {
for (z = a ; z = b ; z++) {
c = pow(n, x);
d = pow(n, y);
e = pow(n, z);
f = c + d;
if (e = f) {
printf("(%d , %d , %d) : %d", x,y,z,n);
}
}
}
}
}
I'm a novice in C.
C correction
Try changing
if (e=f)
into
if (e==f)
The first does assignment, the second tests equality.
(Note that you may also get overflow if the numbers tested get larger than your datatype.)
Maths approach
If y==x, then:
n^x + n^x = n^z
2n^x = n^z
=> n == 0 or n == 2
Now, assume y>x and n!=0.
n^x + n^y = n^z
n^x ( 1 + n^(y-x)) = n^z
=> 1+n^(y-x) = n^(z-x)
=> 1 = 0 ( modulo n)
=> impossible unless n==0 (in which case any x,y works) or n==1 (which does not work)
So this equation has solutions for any x,y if n==0.
Otherwise, the only solutions are with n==2, x==y and z=x+1.
Change
if (e = f)
to
if (e == f)
The first one assigns f to e, enable compiler warnings for such mistakes. The second one equates the LHS to the RHS.
Secondly, assuming your program is a brute force, i.e., loops for all values of x, y and z, you might want to change this statement:
for (z = a ; z = b ; z++)
to
for (z = a ; z < b ; z++)
Your implementation is O(n^4) , actually it can be done in O(n^3) .Here is the code
for (n = a ; n <= b ; n++) {
for (x = a ; x < b ; x++) {
for (y = a ; y < b ; y++) {
{
c = pow(n, x);
d = pow(n, y);
f = c + d;
e = pow(f,1.0/n);
if (e >= a && e < b) {
z = e;
printf("(%d , %d , %d) : %d", x,y,z,n);
}
}
}
}
}
So I was making a program that computes Pythagorean triples, as long as c is lower than the number entered by the user. So I used 3 while loops to accomplish this. What I also want to accomplish is print to the screen, the set of triples that has the thinnest interior angle, has to be a right-angled triangle. Basically, I calculated using the sine law the smallest angle for each of the triples, and then stored that smallest in an array, and right after it the three indexes of the array represent its corresponding triples. Then I made a method to compare each angle from the triples and if one was greater to store it in the initial four spots of the array. I am currently not worrying about the array size and have declared it as 9999. So the problem is that when I compare more than 1 set of triples, the program does not make the 1st set of indexes in the array equal to the triple with the smallest angle. I agree that the procedure that I have used is very inefficient and time consuming, but if you could give me some sort of solution or even guide me in the right direction I'd appreciate it. Thanks. Oh and here is my code,
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
static int a[9999];
int main(void)
{
int side1, side2, hyp, num;
int i = 0;
int j;
side1 = 1;
hyp = 0;
printf("Please enter a number\n");
scanf("%d", &num);
while (side1 < num) {
side2 = 1;
while (side2 < num) {
hyp = 1;
while (hyp < num) {
if (side1 * side1 + side2 * side2 == hyp * hyp && side1 < side2) {
printf("The side lengths are %d,%d,%d\n", side1, side2, hyp);
float angle1 = (asin((float) side1 / hyp) * (180 / PI));
float angle2 = (asin((float) side2 / hyp) * (180 / PI));
if (angle1 > angle2) {
a[i] = (int)angle2;
a[i + 1] = side1;
a[i + 2] = side2;
a[i + 3] = hyp;
} else if (angle2 > angle1) {
a[i] = (int)angle1;
a[i + 1] = side1;
a[i + 2] = side2;
a[i + 3] = hyp;
} else {
a[i] = (int)angle1;
a[i + 1] = side1;
a[i + 2] = side2;
a[i + 3] = hyp;
}
i=i+4;
}
hyp++;
}
side2++;
}
side1++;
}
a[i+1]=99.99;
a[i+2]=99.99;
a[i+3]=99.99;
a[i+4]=99.99;
compare(i);
return (0);
}
void compare(int i)
{
int j;
for(j=0;j<i;j=j+4)
{
if (a[0]>a[j+4])
{
a[0]=a[j+4];
a[1]=a[j+5];
a[2]=a[j+6];
a[3]=a[j+7];
}
//printf("%d\n",a[0]);
}
printf("The thinnest triangle is formed by (%d , %d , %d)", a[1], a[2], a[3]);
}
Oh one more thing, the reason I have made some indexes 99.9 is so that when the loop is checking and it is not the last triple, I do not want an error,since the loop will have nothing further to compare the previous triples to. Ok I changed it to one equal sign, but now the output is always 99,99,99.
Perhaps the four statements starting with a[0]==a[j+4] should be using = instead of ==.
switch your assignments to single equal signs = instead of double ones ==.
void compare(int i)
{
int j;
for(j=0;j<i;j=j+4)
{
if (a[0]>a[j+4])
{
a[0] = a[j+4]; // <- here,
a[1] = a[j+5]; // <- here,
a[2] = a[j+6]; // <- here,
a[3] = a[j+7]; // <- and here
}
//printf("%d\n",a[0]);
}
printf("The thinnest triangle is formed by (%d , %d , %d)", a[1], a[2], a[3]);
}
Given n positive real numbers in an array, find whether there exists a triplet
among this set such that, the sum of the triplet is in the range (1,
2). Do it in linear time and constant space.
the array is not ordered.
numbers are positive
numbers are real numbers
Any help would be greatly appreciated. Thanks.
The trick is to figure out a way to categorize the possible solutions and come up with a linear-time constant-space solution for each.
Consider the three ranges X = (0,2/3), Y = [2/3,1], Z = (1,2). At most one value can come from Z (if two values came from Z, then the sum would exceed 1+1=2). Similarly, at least one value must come from X. Suppose there were 3 values a <= b <= c so that 1 <= a+b+c <= 2 . Then, consider what possible classes of solutions are feasible:
A) `a \in X, b \in X, C \in X`
B) `a \in X, b \in X, C \in Y`
C) `a \in X, b \in X, C \in Z`
D) `a \in X, b \in Y, C \in Y`
E) `a \in X, b \in Y, C \in Z`
So how can we test each case?
Case A is incredibly easy to test: the sum is guaranteed to be below 2, so we just need to test the largest sum (largest 3 elements in X) exceeds 1.
Case C is incredibly easy to test: since the sum is guaranteed to be above 1, we only need to check if the sum is below 2. So in order to do that, we just need to test the smallest 2 values in X and the smallest value in Z
Cases D and E are similar to C (since the sum must be at least 4/3 > 1, choose the smallest possible values in each class).
Case B is the only tricky case. 0 < a+b < 4/3 and 2/3 <= c <= 1. To handle case B, we consider these intervals : X1 = (0, 1/2), X2 = [1/2 2/3), Y = [2/3, 1].
This results in following three valid cases :
B1. a in X1, b in X2, c in Y
B2. a in X1, b in X1, c in Y
B3. a in X2, b in X2, c in Y
Case B1 & B3 : Sum of three numbers is always greater than 1 so we take minimum values and check if it is smaller than 2 or not.
Case B2 : Sum of three numbers is always less than 2, so we take maximum sum and check if is greater than 1 or not.
So to summarize, the tests are:
|X| >= 3 and Xmax(1) + Xmax(2) + Xmax(3) >= 1
|X| >= 2, |Z| >= 1, and Xmin(1)+Xmin(2)+Zmin(1) <= 2
|X| >= 1, |Y| >= 2, and Xmin(1)+Ymin(1)+Ymin(2) <= 2
|X| >= 1, |Y| >= 1, |Z| >= 1, and Xmin(1)+Ymin(1)+Zmin(1) <= 2
|X| >= 2, |Y| >= 1, and Xmax(1) + Xmax(2) + Ymin(1) < 2
|X| >= 2, |Y| >= 1, and Xmin(1) + Xmin(2) + Ymax(1) > 1)
Each test can be performed in linear time and constant space (you only need to find Xmax(1), Xmax(2), Xmax(3), Xmin(1), Xmin(2), Ymin(1), Ymin(2), Ymax(1), Zmin(1), all of which can be found in one pass even if the data is not sorted)
So, you have an array of double data types of length n. Intialize three variables a,b and c as first 3 values of array.Now,iterate from i = 3 to n and check the following: 1)Check if sum falls in (1, 2),if it does then return true. 2)If not, then check if sum is greater than 2,if so, then replace MAX(a,b,c) to current element arr[i]. 3)Otherwise sum must be less than 1 then replace MIN(a,b,c) to current element arr[i].And finally after coming out of loop check once again for last triplet if sum falls in (1,2) then return true,otherwise return false.
enter code here
double a=arr[0], b=arr[1], c=arr[2];
for(int i=3 ; i<n ; i++){
// check if sum fall in (1, 2)
if(a+b+c > 1 && a+b+c < 2){
return 1;
}
// if not, then check is sum greater than 2
// if so, then replece MAX(a,b,c) to new number
else if(a+b+c > 2){
if(a>b && a>c){
a = arr[i];
}
else if(b>a && b>c){
b = arr[i];
}
else if(c>a && c>b){
c = arr[i];
}
}
// else then sum must be less than 1
// then replace MIN(a,b,c) to new number
else{
if(a<b && a<c){
a = arr[i];
}
else if(b<a && b<c){
b = arr[i];
}
else if(c<a && c<b){
c = arr[i];
}
}
}
// check for last a, b, c triplet
if(a+b+c > 1 && a+b+c < 2){
return 1;
}
else{
return 0;
}
Question asked is similar to this InterviewBit question. I've made some changes to the solution mentioned below to match exactly what you asked.
There are three conditions:
First, if the sum is between 1 and 2.
Second, if the sum is greater than 2, then the larger element of the three will be replaced with the next element and the process is repeated.
Third, if the sum is less than 1, then the smaller element of the three will be replaced with the next element and same process is repeated.
int Solution::solve(vector<float> &A) {
if(A.size()<3) return 0;
float a = A[0];
float b = A[1];
float c = A[2];
for(int i=3;i<A.size();++i){
if(a+b+c>1 && a+b+c<2)
return 1;
float temp = A[i];
if(a+b+c>=2){
if(a>b && a>c)
a = temp;
else if(b>c && b>a)
b = temp;
else
c = temp;
}
else{
if(a<b && a<c)
a = temp;
else if(b<c && b<a)
b = temp;
else
c = temp;
}
}
if(a+b+c>1 && a+b+c<2) return 1;
return 0;
}
Same question can also be solved using two pointer technique. In this first we'll have to sort the array. But, It's complexity will be more than O(logn).
int Solution::solve(vector<float> &A) {
int n = A.size();
if(n<3) return 0;
sort(A.begin(), A.end());
int l = 0, r = n-1;
while(l<r-1){
float s = A[l]+A[l+1]+A[r];
if(s>=2)
r = r-1;
else if(s<1)
l = l+1;
else return 1;
}
return 0;
}
This problem can easily be solved in linear runtime time using the sliding window sum approach. In this case, we will use a window of size 3. This is also called the 'moving sum algorithm'.
Algorithm Below
1> Prepare the window of size 3 with the first 3 elements
2> IF (array.len <= 3): CHECK IF window-sum is in the range (1,2), then RETURN accordingly
3> FOR i = 3 UPTO (array.len-1)
3.1> SORT the window (3log3 = constant time operation)
3.2> IF window-sum is in the range (1,2): RETURN 1 or TRUE
3.3> ELSE IF window-sum < 1: Replace the smallest element in the window (window[0]) with array[i]
3.4> ELSE IF window-sum > 2: Replace the largest element in the window (window[2]) with array[i]
4> Outside the loop, check the FINAL window sum and RETURN accordingly.
Access the Python code here. Star the repository, please!
Java code for the solution given by #soul Ec.
we need to modify the case B.
let say our numbers are a+b+c
there are three ranges
x1 x2 y
(0,1/2) (1/2,2/3) (2/3,1)
we have 4 possibilities
1. x1 + x1 +y
2. x2 + x2 +y
3. x1 + x2 +y
4 x2 + x1 +y
here case 3 and 4 are identical as sum of it will be same. so we have 3 cases only.
1. x1 + x1 + y it is always <2 ( do x1max+x1max+ymax <2 to verify)
so we have to check if x1max(1)+x1max(2)+ymax(1) > 1
2. x2 + x2 + y it is always >1 ( do x2min+x2min+ymin >1 to verify)
so we have to check if x2min(1)+x2min(2)+ymin(1) <=2
3. x1 + x2 + y it is always >1 (do x1min+x2min+ymin >1 to verify)
so we have to check if x1min(1)+x2min(1)+ymin(1)<=2
public static int solve(ArrayList<String> A) {
double d[]= new double[A.size()];
for(int i=0;i<A.size();i++) {
d[i]= Double.parseDouble(A.get(i));
}
double range1 = 0;
double range2 = (double) 2/3;
double range3 = 1;
double range4 = 2;
double range02 =(double) 1/2;
// min and max in range (0,2/3)
double min1= Double.MAX_VALUE;
double min2=Double.MAX_VALUE;
double min3=Double.MAX_VALUE;
double max1= Double.MIN_VALUE;
double max2=Double.MIN_VALUE;
double max3=Double.MIN_VALUE;
// min and max in range (2/3,1)
double miny1= Double.MAX_VALUE;
double miny2=Double.MAX_VALUE;
double miny3=Double.MAX_VALUE;
double maxy1= Double.MIN_VALUE;
double maxy2=Double.MIN_VALUE;
double maxy3=Double.MIN_VALUE;
// min and max in range (1,2)
double minz1= Double.MAX_VALUE;
double minz2=Double.MAX_VALUE;
double minz3=Double.MAX_VALUE;
double maxz1= Double.MIN_VALUE;
double maxz2=Double.MIN_VALUE;
double maxz3=Double.MIN_VALUE;
// min and max in range (0,1/2)
double minxx1= Double.MAX_VALUE;
double minxx2=Double.MAX_VALUE;
double minxx3=Double.MAX_VALUE;
double maxx1= Double.MIN_VALUE;
double maxx2=Double.MIN_VALUE;
double maxx3=Double.MIN_VALUE;
// min and max in range (1/2,2/3)
double minyy1= Double.MAX_VALUE;
double minyy2=Double.MAX_VALUE;
double minyy3=Double.MAX_VALUE;
double maxyy1= Double.MIN_VALUE;
double maxyy2=Double.MIN_VALUE;
double maxyy3=Double.MIN_VALUE;
for (int i = 0; i < d.length; i++) {
if (d[i] >= range1 && d[i] < range02) {
if (d[i] < minxx3) {
minxx1=minxx2;
minxx2=minxx3;
minxx3 = d[i];
} else if (d[i] > minxx3 && d[i] < minxx2) {
minxx1=minxx2;
minxx2 = d[i];
} else if (d[i] > minxx3 && d[i] > minxx2 && d[i] < minxx1) {
minxx1 = d[i];
}
if (d[i] > maxx3) {
maxx1=maxx2;
maxx2=maxx3;
maxx3 = d[i];
} else if (d[i] < maxx3 && d[i] > maxx2) {
maxx1=maxx2;
maxx2 = d[i];
} else if (d[i] < maxx3 && d[i] < maxx2 && d[i] > maxx1) {
maxx1 = d[i];
}
}
if (d[i] >= range02 && d[i] < range2) {
if (d[i] < minyy3) {
minyy1=minyy2;
minyy2=minyy3;
minyy3 = d[i];
} else if (d[i] > minyy3 && d[i] < minyy2) {
minyy1=minyy2;
minyy2 = d[i];
} else if (d[i] > minyy3 && d[i] > minyy2 && d[i] < minyy1) {
minyy1 = d[i];
}
if (d[i] > maxyy3) {
maxyy1=maxyy2;
maxyy2=maxyy3;
maxyy3 = d[i];
} else if (d[i] < maxyy3 && d[i] > maxyy2) {
maxyy1=maxyy2;
maxyy2 = d[i];
} else if (d[i] < maxyy3 && d[i] < maxyy2 && d[i] > maxyy1) {
maxyy1 = d[i];
}
}
if (d[i] >= range1 && d[i] < range2) {
if (d[i] < min3) {
min1=min2;
min2=min3;
min3 = d[i];
} else if (d[i] > min3 && d[i] < min2) {
min1=min2;
min2 = d[i];
} else if (d[i] > min3 && d[i] > min2 && d[i] < min1) {
min1 = d[i];
}
if (d[i] > max3) {
max1=max2;
max2=max3;
max3 = d[i];
} else if (d[i] < max3 && d[i] > max2) {
max1=max2;
max2 = d[i];
} else if (d[i] < max3 && d[i] < max2 && d[i] > max1) {
max1 = d[i];
}
}
if (d[i] >= range2 && d[i] < range3) {
if (d[i] < miny3) {
miny1=miny2;
miny2=miny3;
miny3 = d[i];
} else if (d[i] > miny3 && d[i] < miny2) {
miny1=miny2;
miny2 = d[i];
} else if (d[i] > miny3 && d[i] > miny2 && d[i] < miny1) {
miny1 = d[i];
}
if (d[i] > maxy3) {
maxy1=maxy2;
maxy2=maxy3;
maxy3 = d[i];
} else if (d[i] < maxy3 && d[i] > maxy2) {
maxy1=maxy2;
maxy2 = d[i];
} else if (d[i] < maxy3 && d[i] < maxy2 && d[i] > maxy1) {
maxy1 = d[i];
}
}
if (d[i] >= range3 && d[i] <= range4) {
if (d[i] < minz3) {
minz1=minz2;
minz2=minz3;
minz3 = d[i];
} else if (d[i] > minz3 && d[i] < minz2) {
minz1=minz2;
minz2 = d[i];
} else if (d[i] > minz3 && d[i] > minz2 && d[i] < minz1) {
minz1 = d[i];
}
if (d[i] > maxz3) {
maxz1=maxz2;
maxz2=maxz3;
maxz3 = d[i];
} else if (d[i] < maxz3 && d[i] > maxz2) {
maxz1=maxz2;
maxz2 = d[i];
} else if (d[i] < maxz3 && d[i] < maxz2 && d[i] > maxz1) {
maxz1 = d[i];
}
}
}
if(max1+max2+max3>=1 && max1!=Double.MIN_VALUE && max2!=Double.MIN_VALUE && max3!=Double.MIN_VALUE)
return 1;
if(min3+min2+minz3<=2 && min3!=Double.MAX_VALUE && min2!=Double.MAX_VALUE && minz3!=Double.MAX_VALUE )
return 1;
if(min3+miny3+miny2<=2 && min3!=Double.MAX_VALUE && miny3!=Double.MAX_VALUE && miny2!=Double.MAX_VALUE)
return 1;
if(min3+miny3+minz3<=2 && min3!=Double.MAX_VALUE && miny3!=Double.MAX_VALUE && minz3!=Double.MAX_VALUE)
return 1;
if(maxx3+maxx2+maxy3>1 && maxx3!=Double.MIN_VALUE && maxx2!=Double.MIN_VALUE && maxy3!=Double.MIN_VALUE) {
return 1;
}
if(minyy3+minyy2+miny3<=2 && minyy3!=Double.MAX_VALUE && minyy2!=Double.MAX_VALUE && miny3!=Double.MAX_VALUE) {
return 1;
}
if(minxx3+minyy3+miny3<=2 && minxx3!=Double.MAX_VALUE && minyy3!=Double.MAX_VALUE && miny3!=Double.MAX_VALUE) {
return 1;
}
return 0;
}
the solution is in c++(interviewbbit solution)
int Solution::solve(vector<string> &arr) {
int n=arr.size(),i;
vector<float>v;
for(i=0;i<n;i++)
{
v.push_back(stof(arr[i]));
}
float a=v[0],b=v[1],c=v[2];
float mx=0;
for(i=3;i<n;i++)
{
if(a+b+c<2 && a+b+c>1)
return 1;
else if(a+b+c>2)
{
if(a>b && a>c)
a=v[i];
else if(b>a && b>c)
b=v[i];
else
c=v[i];
}
else
{
if(a<b && a<c)
a=v[i];
else if(b<a && b<c)
b=v[i];
else
c=v[i];
}
}
if(a+b+c>1 && a+b+c<2)
return 1;
else
return 0;
}
We can easily do it in O(n) , we just need to find three minimum positive real numbers ,which we can find in one iteration and in the end if their summation lies in between (1,2) then return 1 else return 0.
The problem in its whole as stated is undecidable. This is due to the fact that for any two real numbers a and b it cannot be decided if a > b holds (also see this answer of me). But you have to do at least one comparison of a real number against an integer value to solve that problem. Comparing against an integer doesn't make the problem easier since you could have a real number which is 2,00...001 where there is an arbitrary number of zeros between the digits 2 and 1 which you don't know beforehand. Storing such real numbers (probably not every one, but many of them) in the main memory of a computer is not a big problem for such specific ones, since they can be represented by an approximation algorithm.
for further information I suggest reading Complexity Theory of Real Functions
I am trying to write a program to perform point operations on a elliptic curve in a prime field I am using the standard formulaes for point additions and doubling in my code and these operations are performed by functions that are called but I am getting output for certain points but not all so please help me to fix the problem that are present in this code.
structure point_multiply(int x, int y, int k )
{
int xk;
int yk,m;
xk=x;
yk=y;
m=1;
int xL,yL,s,e;
e=findInverse((2*yk),211);
if((((3*(xk*xk))*e)% 211)>0)
{s = (((3*(xk*xk))*e)% 211);
}
else
s=(((3*(xk*xk))*e)% 211)+ 211;
if((((s*s)- (2*xk)) % 211)>0)
{xL=(((s*s)- (2*xk)) % 211);
}
else
xL=(((s*s)- (2*xk)) % 211) + 211;
if(((-yk+ s*(xk-xL)) % 211) > 0)
yL=(-yk+ s*(xk-xL)) % 211;
else
yL=(-yk+ s*(xk-xL)) % 211 + 211;
xk=xL;
yk=yL;
m=m+1;
while(k>m)
{
sn=point_addition(xk,yk,x,y);
xk=sn.a;
yk=sn.b;
m++;
}
s1.a=xk;
s1.b=yk;
return s1;
}
structure point_addition(int x1, int y1, int x2, int y2)
{
int s,xL,yL;
if((x1-x2)!=0)
{
if ( x1 == 0 && y1 == 0 )
{
xL = x2;
yL = y2;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( x2 == 0 && y2 == 0 )
{
xL = x1;
yL = y1;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( y1 == -y2 )
{
xL = yL = 0;
s7.a=xL;
s7.b=yL;
return s7;
}
l=findInverse((x1-x2),211);
if ((((y1-y2)*l) % 211)>=0)
s=((((y1-y2)*l) % 211));
else
s=(((y1-y2)*l) % 211) + 211;
if ((((s*s)-(x1+x2)) % 211)>0)
xL= (((s*s)-(x1+x2)) % 211) ;
else
xL= (((s*s)-(x1+x2)) % 211) + 211;
if(((-y1+s*(x1-xL)))>=0)
yL= ((-y1+s*(x1-xL)) % 211);
else
yL= ((-y1+s*(x1-xL)) % 211) + 211;
}
else
{
xL= 0 ;
yL= 0;
}
s7.a= xL;
s7.b= yL;
return s7 ;
}
int findInverse(int a, int b)
{
int x[3];
int y[3];
int quotient = a / b;
int remainder = a % b;
x[0] = 0;
y[0] = 1;
x[1] = 1;
y[1] = quotient * -1;
int i = 2;
for (; (b % (a%b)) != 0; i++)
{
a = b;
b = remainder;
quotient = a / b;
remainder = a % b;
x[i % 3] = (quotient * -1 * x[(i - 1) % 3]) + x[(i - 2) % 3];
y[i % 3] = (quotient * -1 * y[(i - 1) % 3]) + y[(i - 2) % 3];
}
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
if(x[(i - 1) % 3]<0)
return x[(i - 1) % 3]+211;
else
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
return x[(i - 1) % 3];
}
Edited and added main c code which uses these function to perform elliptic curve cryptography
int main()
{
int y,z=0,x=2,i[200],j[200],h=0,g,k;
while(x<200)
{
y=sqrt((x*x*x)-4);
z=modulo(y,211);
if(z!=0)
{
i[h]=x;
j[h]=z;
s[h].a=i[h];
s[h].b=j[h];
s[h+1].a=i[h];
s[h+1].b=(211 - j[h]);
printf("\nh=%d X= %d Y= %d \nh=%d X= %d Y= %d",h,s[h].a,s[h].b,h+1,s[h+1].a,s[h+1].b);
h=h+2;
}
x++;
}
printf("The total no of points we have on our elliptic curve for cryptography is %d",h-1);
x=5;
y=11;
printf("\n %d %d\n",x,y );
printf("\nEnter A number between 0 and the private key");
scanf("%d",&k);
s2=point_multiply(x,y,k);
printf("\n The public key is \n %d %d \n ",s2.a,s2.b );
printf("Enter a RANDOM number to generate the cipher texts");
scanf("\n%d",&g);
s3= point_multiply(x,y,g);
s4=point_multiply(s2.a,s2.b,g );
label:
printf("\n Enter a number to send");
scanf("%d",&h);
s6=point_addition(s4.a,s4.b,s[h].a,s[h].b);
printf("The points to be sent are X= %d Y=%d",s[h].a,s[h].b);
printf(" \n X= %d Y=%d\n X = %d Y= %d ",s3.a,s3.b,s6.a,s6.b);
//RECIEVER
s8=point_multiply(s3.a,s3.b,k);
s9=point_addition((s8.a) ,-((s8.b)%211),s6.a,s6.b);
printf(" The decrypted points are \n %d %d",s9.a,s9.b);
printf("\n If you have more no to send press 1 else press 0");
scanf("\n %d", &x1);
if(x1==1)
goto label;
else
return 0;
}
s1, s2, s3 etc are structures which hold a 2 integers which act as x and y co-ordinates
I am getting output by entering k=3,g=4, h=5 and many other cases mostly with small numbers but not for larger numbers. What could be wrong with the code?
Further edit: I guess that normal square root method is not applicable to find square roots of a modular no?.. Please tell me how to find the modular square root of a no?