I've decided to create a simple demo, dividing a polygon into triangle set. Here what i've got so far:
A sequential vertex list is given (P1) forming polygon edges (polygon is not convex in most cases); a triangle set is needed
Loop through all the vertices within the polygon P1 and find the one (v), which will satisfy next clauses:
remove v from polygon and save the new one to P2 previous vertex to v
connected to its next one form a
line which do not cross any of P2
edges
v is not inside P2
If these are satisfied, we can replace P1 with (P2 + triangle( prev(v), v, next(v)) ) and repeat this action until P1 contains more than 3 vertices.
So, the questions are: is this algorithm correct and how it could be implemented using C / C++ using the most obvious and simple way?
I think you're describing the ear clipping method. There's code for that method at http://cs.smith.edu/~orourke/books/ftp.html ; it's the code described in the book Computational Geometry in C.
Seems that i'm done with this algorithm implementation. Please, verify it someone. Thanks!
typedef struct Point
{
float x, y;
};
class MooPolygon
{
private:
vector<Point> points;
int isVertexEar(int n, const vector<Point> &p)
{
return (isVertexInsideNewPoly(n, p) && !isEdgeIntersect(n, p));
}
int isEdgeIntersect(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 0, cnt = a.size(), prev = (cnt + (n - 1)) % cnt, next = n % cnt;
Point v1 = a[prev], v2 = a[next];
for (size_t i = 0, j = cnt - 1; i < cnt; j = i++)
{
if (prev == i || prev == j || next == i || next == j)
continue;
Point v4 = a[j], v3 = a[i];
float denominator = ((v4.y - v3.y) * (v2.x - v1.x)) - ((v4.x - v3.x) * (v2.y - v1.y));
if (!denominator)
continue;
float ua = (((v4.x - v3.x) * (v1.y - v3.y)) - ((v4.y - v3.y) * (v1.x - v3.x))) / denominator;
float ub = (((v2.x - v1.x) * (v1.y - v3.y)) - ((v2.y - v1.y) * (v1.x - v3.x))) / denominator;
//float x = v1.x + (ua * (v2.x - v1.x)), y = v1.y + (ua * (v2.y - v1.y));
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
{
c = 1;
break;
}
}
return c;
}
int isVertexInsideNewPoly(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 1;
for (size_t i = 0, j = a.size() - 1; i < a.size(); j = i++)
{
if ((((a[i].y <= v.y) && (v.y < a[j].y)) || ((a[j].y <= v.y) && (v.y < a[i].y))) && (v.x > (a[j].x - a[i].x) * (v.y - a[i].y) / (a[j].y - a[i].y) + a[i].x))
c = !c;
}
return c;
}
float dist(Point a, Point b)
{
return sqrt( ((a.x - b.x) * (a.x - b.x)) + (((a.y - b.y) * (a.y - b.y))) );
}
public:
void push(const Point &p)
{
for (size_t i = 0; i < points.size(); i++)
{
if (dist(points[i], p) < 7.f)
{
points.push_back(points[i]);
return;
}
}
points.push_back(p);
}
void pop()
{
if (points.size() > 0)
points.pop_back();
}
void clear()
{
points.clear();
}
Point v(int index)
{
return points[index];
}
size_t size()
{
return points.size();
}
void triangulate()
{
vector<Point> a;
for (size_t i = 0; i < points.size(); i++)
{
a.push_back(points[i]);
}
points.clear();
for (size_t t = a.size() - 1, i = 0, j = 1; i < a.size(); t = i++, j = (i + 1) % a.size())
{
if (a.size() == 3)
{
points.push_back(a[0]);
points.push_back(a[1]);
points.push_back(a[2]);
break;
}
if (isVertexEar(i, a))
{
points.push_back(a[t]);
points.push_back(a[i]);
points.push_back(a[j]);
a.erase(a.begin() + i, a.begin() + i + 1);
t = a.size() - 1;
i = 0;
j = 1;
}
}
}
};
The code has an error on the line below. The line is in the for loop in the push() function of your class:
points.push_back(points[i]);
You are not passing the pushed Point, but an empty element of the vector itself. I changed the line to
points.push_back(p);
and it worked.
Related
I am trying to create a program in C to check if the lines of rectilinear polygon intersect each other at any point.
I only need simple rectilinear polygons that do not intersect at any point. It can be counter-clockwise or clockwise.
The direction values will be less than 10. NS direction must alternate with WE direction and vice versa.
The inputs being passed are in the form of direction from an input file such as; and also shown in the pictures:
S 2 E 4 S 2 E 4 N 2 W 4 N 2 W 4
I tried to store points in a two-dimensional array with every point being checked as true, but I am unable to figure out how to move in case of counter and clockwise direction as the points could be N4 E6 or S4 W6. In such a case if I add when the value is N-4 (x,y) = (0,4) and subtract when S-4 (x,y) = (0,-4) that would fail when using it as index in array.
int arr[10][10];
int xPrime = 0, yPrime = 0;
bool checkContinuity(int y, const char * dir ){
if(strcmp(dir, "S")==0){
y = -y;
cols = y;
int j;
for(j = cols; j >= 0; j--){
if(arr[xPrime][j] == 1 && j != yPrime){
return false;
}
arr[xPrime][j] = 1;
printf(" %d ", j);
}
yPrime -= y;
if(yPrime < 0)
yPrime = -yPrime;
}
else if(strcmp(dir, "W")==0){
y = -y;
cols = y;
int j;
for(j = cols; j >= 0; j--){
if(arr[j][yPrime] == 1 && j != xPrime && (j != 0 && yPrime != 0)){
return false;
}
arr[j][yPrime] = 1;
printf(" %d ", j);
}
xPrime -= y;
if(xPrime < 0)
xPrime = -xPrime;
}
else if(strcmp(dir, "N")==0){
cols = y;
int j;
for(j = 0; j <= cols; j++){
if(arr[xPrime][j] == 1)
return false;
arr[xPrime][j] = 1;
printf(" %d ", j);
}
yPrime += y;
}
else if(strcmp(dir, "E")==0){
cols = y;
int j;
for(j = 0; j <= cols; j++){
if(arr[j][yPrime] == 1 && j != xPrime)
return false;
arr[j][yPrime] = 1;
printf(" %d ", j);
}
xPrime += y;
}
else
return false;
return true;
}
It might be easier to store the actual polygon rather than all possible
points of the plane. We are then not restricted by the choice of the
point array (arr in your code). See this working example:
the polygon is stored in the int-array P = {0, 0, x1, y1, x2, y2, ...}
segments are two-point polygons. The function 'intersection' checks if
two such segments Q and P intersect;
if so, returns the intersection coordinates.
It uses the helper function 'between' to ckeck if one number is between two others.
the function 'next' calculates the next point of the polygon, assuming
the input is provided as char-string (eg: "S2E4S2E4N2W4N2W4")
In the function main we now loop over all segments, and check if they intersect with
any previous one.
Of course, the input should at some point be checked for sanity etc.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void
next( const char *s,
int *v )
{
v[2] = v[0];
v[3] = v[1];
int step = s[1] - '0';
switch(s[0]) {
case 'S': v[3] -= step; break;
case 'N': v[3] += step; break;
case 'W': v[2] -= step; break;
case 'E': v[2] += step; break;
}
}
int
between( int x,
int a,
int b )
{
return a < b ? x >= a && x <= b : x >= b && x <= a;
}
int
intersection( int *P,
int *Q,
int *R )
{
if(P[0] == P[2] && Q[1] == Q[3]){ // P vertical, Q horizontal (w.l.o.g.)
if(between(P[0], Q[0], Q[2]) && between(Q[1], P[1], P[3])){
R[0] = P[0];
R[1] = Q[1];
return 1;
} else
return 0;
}else if(Q[0] == Q[2] && P[1] == P[3])
return intersection(Q, P, R);
else return 0;
}
int
main() {
char *s = "S2E4S2E4N2W4N2W4";
int n = strlen(s) / 2, // number of steps
*P = calloc((n + 1) * 2, sizeof(int)), // polygon
R[2]; // intersection
if(!P) exit(137);
for(int k = 0; k < n; k++){
next(s + 2 * k, P + 2 * k);
for(int j = 0; j < k - 1; j++) {
if(intersection(P + k * 2, P + j * 2, R)) {
printf("Intersection at: %d, %d\n", R[0], R[1]);
exit(0);
}
}
}
printf("No intersection\n");
}
I tried to implement C code for Wavelet transform in FPGA (Zynq ZC 702) but the code get stuck and this is because of memory problem so I should optimize my code but I don't know how.
Can anyone please give me some ideas how to do that ?
This is the main of the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "wavemin.h"
#include "waveaux.h"
#include "waveaux.c"
#include "wavemin.c"
int main() {
printf("Hello World1 \n\r");
wave_object obj;
wt_object wt;
float *inp, *out;
int N, i, J,k;
float temp[1280] = {};
char *name = "db4";
obj = wave_init(name);
printf("Hello World2 \n\r");
N = 1280;
inp = (float*)malloc(sizeof(float) * N);
out = (float*)malloc(sizeof(float) * N);
//wmean = mean(temp, N);
for (i = 0; i < N; ++i) {
inp[i] = temp[i];
printf("Hello World3 \n\r");
//printf("%g \n", inp[i]);
}
J = 4; //Decomposition Levels
wt = wt_init(obj, "dwt", N, J); // Initialize the wavelet transform object
printf("Hello World4 \n\r");
setDWTExtension(wt, "sym"); // Options are "per" and "sym". Symmetric is the default option
printf("Hello World5 \n\r");
setWTConv(wt, "direct");
printf("Hello World6 \n\r");
dwt(wt, inp); // Perform DWT
printf("Hello World7 \n\r");
//getDWTAppx(wt, out, wt->length[0]);
// printf("Approximation Coefficients Level 1 \n");
// for (i = 0; i < wt->length[0]; ++i) {
// printf("%g ", out[i]);
// }
// printf("\n\n");
for (k = 1; k <= J; ++k) {
getDWTDetail(wt, out, wt->length[k], k);
printf("Detail Coefficients Level %d Length %d \n",
k, wt - length[k]);
for (i = 0; i < wt->length[k]; ++i) {
printf("%g ", out[i]);
}
printf("\n\n");
}
wt_summary(wt);// Prints the full summary.
printf("Hello World8 \n\r");
wave_free(obj);
wt_free(wt);
free(inp);
free(out);
return 0;
}
The other part of the code where there is the function used in the main function:
#include "wavemin.h"
wave_object wave_init(char *wname) {
wave_object obj = NULL;
int retval;
retval = 0;
if (wname != NULL) {
retval = filtlength(wname);
}
obj = (wave_object)malloc(sizeof(struct wave_set) + sizeof(float) * 4 *
retval);
obj->filtlength = retval;
obj->lpd_len = obj->hpd_len = obj->lpr_len = obj->hpr_len = obj->filtlength;
strcpy(obj->wname, wname);
if (wname != NULL) {
filtcoef(wname, obj->params, obj->params + retval, obj->params + 2 *
retval, obj->params + 3 * retval);
}
obj->lpd = &obj->params[0];
obj->hpd = &obj->params[retval];
obj->lpr = &obj->params[2 * retval];
obj->hpr = &obj->params[3 * retval];
return obj;
}
wt_object wt_init(wave_object wave, char *method, int siglength, int J) {
int size, i, MaxIter;
wt_object obj = NULL;
size = wave->filtlength;
MaxIter = wmaxiter(siglength, size);
if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(float) *
(siglength + 2 * J * (size + 1)));
obj->outlength = siglength + 2 * J * (size + 1); // Default
strcpy(obj->ext, "sym"); // Default
}
obj->wave = wave;
obj->siglength = siglength;
obj->J = J;
obj->MaxIter = MaxIter;
strcpy(obj->method, method);
if (siglength % 2 == 0) {
obj->even = 1;
}
else {
obj->even = 0;
}
strcpy(obj->cmethod, "direct"); // Default
obj->cfftset = 0;
obj->lenlength = J + 2;
obj->output = &obj->params[0];
if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
for (i = 0; i < siglength + 2 * J * (size + 1); ++i) {
obj->params[i] = 0.0;
}
}
//wave_summary(obj->wave);
return obj;
}
static void dwt_sym(wt_object wt, float *inp, int N, float *cA, int len_cA,
float *cD, int len_cD) {
int i, l, t, len_avg;
len_avg = wt->wave->lpd_len;
for (i = 0; i < len_cA; ++i) {
t = 2 * i + 1;
cA[i] = 0.0;
cD[i] = 0.0;
for (l = 0; l < len_avg; ++l) {
if ((t - l) >= 0 && (t - l) < N) {
cA[i] += wt->wave->lpd[l] * inp[t - l];
cD[i] += wt->wave->hpd[l] * inp[t - l];
printf("world1 \n\r");
}
else if ((t - l) < 0) {
cA[i] += wt->wave->lpd[l] * inp[-t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[-t + l - 1];
printf("world2 \n\r");
}
else if ((t - l) >= N) {
cA[i] += wt->wave->lpd[l] * inp[2 * N - t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[2 * N - t + l - 1];
printf("world3 \n\r");
}
}
}
}
void dwt(wt_object wt, float *inp) {
int i, J, temp_len, iter, N, lp;
int len_cA;
float *orig, *orig2;
temp_len = wt->siglength;
J = wt->J;
wt->length[J + 1] = temp_len;
wt->outlength = 0;
wt->zpad = 0;
orig = (float*)malloc(sizeof(float) * temp_len);
orig2 = (float*)malloc(sizeof(float) * temp_len);
for (i = 0; i < wt->siglength; ++i) {
orig[i] = inp[i];
printf("Hello1 \n\r");
}
if (wt->zpad == 1) {
orig[temp_len - 1] = orig[temp_len - 2];
printf("Hello2 \n\r");
}
N = temp_len;
lp = wt->wave->lpd_len;
if (!strcmp(wt->ext, "sym")) {
//printf("\n YES %s \n", wt->ext);
i = J;
while (i > 0) {
N = N + lp - 2;
N = (int)ceil((float)N / 2.0);
wt->length[i] = N;
wt->outlength += wt->length[i];
i--;
}
wt->length[0] = wt->length[1];
wt->outlength += wt->length[0];
N = wt->outlength;
printf("Hello3 \n\r");
for (iter = 0; iter < J; ++iter) {
len_cA = wt->length[J - iter];
N -= len_cA;
dwt_sym(wt, orig, temp_len, orig2, len_cA, wt->params + N, len_cA);
temp_len = wt->length[J - iter];
printf("Hello4 \n\r");
if (iter == J - 1) {
for (i = 0; i < len_cA; ++i) {
wt->params[i] = orig2[i];
printf("Hello5 \n\r");
}
} else {
for (i = 0; i < len_cA; ++i) {
orig[i] = orig2[i];
printf("Hello6 \n\r");
}
}
}
} else {
printf("Signal extension can be either per or sym");
exit(-1);
}
free(orig);
free(orig2);
}
void setDWTExtension(wt_object wt, char *extension) {
if (!strcmp(extension, "sym")) {
strcpy(wt->ext, "sym");
} else {
printf("Signal extension can be either per or sym");
exit(-1);
}
}
void setWTConv(wt_object wt, char *cmethod) {
if (!strcmp(cmethod, "direct")) {
strcpy(wt->cmethod, "direct");
}
}
void getDWTDetail(wt_object wt, float *detail, int N, int level) {
/*
returns Detail coefficents at the jth level where j = 1,2,.., J
and Wavelet decomposition is stored as
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
Use getDWTAppx() to get A(J)
Level 1 : Length of D(J), ie N, is stored in wt->length[1]
Level 2 :Length of D(J-1), ie N, is stored in wt->length[2]
....
Level J : Length of D(1), ie N, is stored in wt->length[J]
*/
int i, iter, J;
J = wt->J;
if (level > J) {
printf("The decomposition only has %d levels", J);
}
iter = wt->length[0];
for (i = 1; i < level; ++i) {
iter += wt->length[i];
}
for (i = 0; i < N; ++i) {
detail[i] = wt->output[i + iter];
}
}
void getDWTAppx(wt_object wt, float *appx, int N) {
/*
Wavelet decomposition is stored as
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
Length of A(J) , N = wt->length[0]
*/
int i;
for (i = 0; i < N; ++i) {
appx[i] = wt->output[i];
}
}
void wt_summary(wt_object wt) {
int i;
int J, t;
J = wt->J;
printf("Wavelet Coefficients are contained in vector : %s \n", "output");
printf("\n");
printf("Approximation Coefficients \n");
printf("Level %d Access : output[%d] Length : %d \n",
1, 0, wt->length[0]);
printf("\n");
printf("Detail Coefficients \n");
t = wt->length[0];
for (i = 0; i < J; ++i) {
printf("Level %d Access : output[%d] Length : %d \n",
i + 1, t, wt->length[i + 1]);
t += wt->length[i + 1];
}
printf("\n");
}
void wave_free(wave_object object) {
free(object);
}
void wt_free(wt_object object) {
free(object);
}
enter image description here
In your code
Always check if malloc has returned non NULL value
Check your stack and heap settings in the linker file as you declare massive local variables and do a lots of mallocs - I suspect the (nomen omen)stack overflow, or failed mallocs.
Is it a bare metal program or you run it under some kind of OS?
Just for a matter of style and concision, I would rewrite this:
if (siglength % 2 == 0) {
obj->even = 1;
}
else {
obj->even = 0;
}
Into the following code:
obj->even = !(siglength % 2);
Or, alternatively:
obj->even = (siglength % 2) ? 0 : 1;
Also, I think there is room for optimization in this function:
static void dwt_sym(wt_object wt, float *inp, int N, float *cA, int len_cA,
float *cD, int len_cD) {
int i, l, t, len_avg;
len_avg = wt->wave->lpd_len;
for (i = 0; i < len_cA; ++i) {
t = 2 * i + 1;
cA[i] = 0.0;
cD[i] = 0.0;
for (l = 0; l < len_avg; ++l) {
if ((t - l) >= 0 && (t - l) < N) {
cA[i] += wt->wave->lpd[l] * inp[t - l];
cD[i] += wt->wave->hpd[l] * inp[t - l];
printf("world1 \n\r");
}
else if ((t - l) < 0) {
cA[i] += wt->wave->lpd[l] * inp[-t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[-t + l - 1];
printf("world2 \n\r");
}
else if ((t - l) >= N) {
cA[i] += wt->wave->lpd[l] * inp[2 * N - t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[2 * N - t + l - 1];
printf("world3 \n\r");
}
}
}
}
First, you are always referring to t - 1 and never t itself, so why not have:
t = 2 * i;
And, I can guess that a lot of computation can be placed outside of the inner loop... If you want to optimize, there are many good candidate here.
One last word about optimization!
You should first profile your software and see where you spend the most time before thinking about optimization. You cannot optimize "in the air" without knowing where your software does really struggle. Consider using gprof.
PS: You should never ever use the letter l (ell) as a variable... it is way to close from the number 1 (one). Consider changing this is also, it can improve the reading.
Im making a program to calculate convex hull length of 2D points.
On the input there is a number of points n and then the coordinates of each point.
for example:
6
-8 -3
-6 1
-5 -2
-3 1
-3 4
2 18
and output is simply the length of the convex hull.
my code looks like this so far:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct point
{
double x;
double y;
}POINT,VECTOR;
POINT b[1000];
VECTOR normal;
int n;
int upper_lower(int i, VECTOR ab, double c) {
double x, y,result;
y = b[i].y;
x = normal.x*b[i].x;
result = -(x + c) / normal.y;
if (y>result) return 1;
if (y == result) return 0;
else
return -1;
}
int ccw(VECTOR v,VECTOR v2)
{
double cp;
cp = v2.x*v.y - v2.y*v.x;
if (cp == abs(cp)) return 1;
else
return -1;
}
double vector_length(VECTOR v)
{
return sqrt(pow(v.x, 2) + pow(v.y, 2));
}
int cmp_points(const void *p1, const void *p2)
{
const POINT *pt1 = p1;
const POINT *pt2 = p2;
// do primary compare on x
if (pt1->x > pt2->x)
return 1;
if (pt1->x < pt2->x)
return -1;
// pt1->x == pt2->x - do secondary compare on y...
if (pt1->y > pt2->y)
return 1;
if (pt1->y < pt2->y)
return -1;
// pt1 == pt2
return 0;
}
int main()
{
int i,poloha,upper[1000],lower[1000],h=0,d=0;
scanf("%d", &n);
if (n <= 0 && n > 1000) return 0;
for (i = 0; i < n; i++)
{
scanf("%lf %lf", &b[i].x, &b[i].y);
}
qsort(b, n, sizeof(POINT), cmp_points);
//split in half
VECTOR ab;
double c;
ab.x = b[n - 1].x - b[0].x;
ab.y = b[n - 1].y - b[0].y;
normal.x = -ab.y;
normal.y = ab.x;
c = -normal.x*b[0].x - (normal.y*b[0].y);
for (i = 0; i < n; i++)
{
poloha = upper_lower(i,ab,c);
if (poloha == 1) upper[h++] = i;
if (poloha == -1) lower[d++]=i;
if (poloha == 0)
{
upper[h++] = i;
lower[d++] = i;
}
}
int j = 0;
double v, length = 0;
VECTOR v1, v2, v3,v4;
v3.x = 0; v3.y = 0;
//lower part
for (i = 0; ; i++)
{
int in = 0;
if (lower[i + 2] < 0)
{
v1.x = b[lower[i + 1]].x - b[lower[0]].x;
v1.y = b[lower[i + 1]].y - b[lower[0]].y;
v2.x = b[lower[i]].x - b[lower[i + 1]].x;
v2.y = b[lower[i]].y - b[lower[i + 1]].y;
lenght += vector_length(v1);
length += vector_length(v2);
break;
}
v1.x = b[lower[i + 1]].x - b[lower[i]].x;
v1.y = b[lower[i + 1]].y - b[lower[i]].y;
v2.x = b[lower[i + 2]].x - b[lower[i]].x;
v2.y = b[lower[i + 2]].y - b[lower[i]].y;
in = ccw(v1, v2);
if (in == 1)
{
length += vector_length(v1);
v3 = v2;
v4 = v1;
}
if (in == -1)
{
length -= vector_length(v4);
if (v3.x != 0 && v3.y != 0)
{
length += vector_length(v3);
v3.x = 0; v3.y = 0;
}
else
{
length += vector_length(v2);
}
}
}
printf("%.3lf", length);
return 0;
}
the problem is that in the last part where I try to compute the length...I just dont know how to finish it..no matter what I try it never works as I want to. Could you guys give me some advice?
I can't see a standard answer, so here's the algorithm:
Choose a point roughly in the centre of your point cloud. Then sort the points radially, by angle from the centre. The topmost point must be in the convex hull, so define it as having an angle of 0.0 and being first in the list.
Now go though. Put point 2 in the "tentative" hull list. Then check point 3. If the angle P1-P2-P3 is concave (relative to the centre point), remove P2 from the list, if it is convex, keep it. Continue like this, backtracking and removing points if they go concave. You only need two points in your "tentative" list, once you have three, they become definite.
You stop when you go full circle and get back to P1.
There are many known convex hull algorithms, one of the simplest of which is the gift wrapping algorithm. Here's an implementation that fits in your program where the points have been input and sorted:
int j = 0; // after sorting, b[0] is leftmost point, must be on an edge
double length = 0;
VECTOR v1, v2, vv;
v1.x = 0, v1.y = 1; // start by measuring angles from vertical
int iv; // index of next edge point
do // find next egde point by minimum angle
{
double lv1 = vector_length(v1), lv2, lv;
double cv = -1; // minimal possible cosine value
for (i = 0; i < n; ++i) if (i != j)
{ // compute cosine of angle between v1 and (b[j]-->b[i]) = v2
v2.x = b[i].x-b[j].x, v2.y = b[i].y-b[j].y;
double c = (v1.x*v2.x + v1.y*v2.y) / lv1 / (lv2 = vector_length(v2));
if (c > cv) cv = c, iv = i, lv = lv2, vv = v2; // new maximum cosine
}
if (v == -1) break;
// printf("%d:%f,%f-->%d:%f,%f = %f\n", j, b[j], iv, b[iv], lv);
length += lv;
v1 = vv; // found edge is new reference edge
} while (j = iv); // repeat while not at start again
printf("%.3lf\n", length);
I've been stuck on this for a while now. I'm writing an algorithm in C to pull out the coefficients of a polynomial using Lagrange's interpolation method.
My code partially works, for instance if we do the first example here http://en.wikipedia.org/wiki/Lagrange_polynomial#Example_1 then the code can print out the first 2 coefficients (0 and 4.834848)
Similarly with example 3 on that article, it will print the 2 coefficients 6 and -11.
I need to be able to accurately get all the coefficients from any set of points. Please advise on the alterations required to the code.
Thanks in advance!
Updated with latest code, 7:57PM, GMT on August 5th. 9 coefficients now working, getting ugly looking. Will investigate iterative process for n degrees tomorrow!
#include<ncursesw/ncurses.h>
#include<math.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define MAX 200
float coeff[MAX], coefftwo[MAX], coeffthree[MAX], coefffour[MAX];
int count;
void main()
{
int n,i,j ;
char ch;
float x[MAX],y[MAX],fp2, coeff1, coeff2;
printf("\n\nn = ");
scanf("%i", &count);
for(i=0; i < count; i++)
{
printf("\n\n The value of x%i= ", i);
scanf("%f",&x[i]);
printf("\n The value of f(x%i)= ", i);
scanf("%f",&y[i]);
}
for(i=0;i<count;i++)
{
coeff1 = 1.0;
coeff2 = 0.0;
coeff3 = 0.0;
coeff4 = 0.0;
coeff5 = 0.0;
coeff6 = 0.0;
coeff7 = 0.0;
coeff8 = 0.0;
coeff9 = 0.0;
for(j=0; j<count; j++)
{
if(i!=j) {
coeff1 = coeff1 * (array[i]-array[j]);
coeff2 -= array[j];
for (int k=j; k < count; k++) {
if ((j!=k) && (k!=i)) {
coeff3 += array[j] * array[k];
for(int l=k; l < count; l++) {
if ((l!=j) && (l!=k) && (l!=i)) {
coeff4 -= array[j] * array[k] * array[l];
for (int m = l; m < count; m++) {
if ((m!=l) && (m!=k) && (m!=j) && (m!=i)) { coeff5 += array[j] * array[k] * array[l] * array[m];
for (int n = m; n < count; n++) {
if ((n!=m) && (n!=l) && (n!=k) && (n!=j) && (n!=i)) {
coeff6 -= array[j] * array[k] * array[l] * array[m] * array[n];
for (int o = n; o < count; o++) {
if ((o!=n) && (o!=m) && (o!=l) && (o!=k) && (o!=j) && (o!=i)) {
coeff7 += array[j] * array[k] * array[l] * array[m] * array[n] * array[o];
for (int p = o; p < count; p++) {
if ((p!=o) && (p!=n) && (p!=m) && (p!=l) && (p!=k) && (p!=j) && (p!=i)) {
coeff8 -= array[j] * array[k] * array[l] *array[m] *array[n] * array[o] * array[p];
for (int q = p; q < count; q++) {
if ((q!=p) && (q!=o) && (q!=n) && (q!=m) && (q!=l) && (q!=k) && (q!=j) && (q!=i)) {
coeff9 += array[j] * array[k] * array[l] * array[m] * array[n] * array[o] * array[p] * array[q];
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
coeff[i] = y[i] / coeff1;
coefftwo[i] = y[i] * coeff2 / coeff1;
coeffthree[i] = y[i] * coeff3 / coeff1;
coefffour[i] = y[i] * coeff4 / coeff1;
coefffive[i] = y[i] * coeff5 / coeff1;
coeffsix[i] = y[i] * coeff6 / coeff1;
coeffseven[i] = y[i] * coeff7 / coeff1;
coeffeight[i] = y[i] * coeff8 / coeff1;
coeffnine[i] = y[i] * coeff9 / coeff1;
}
float coefficientone = 0.0;
float coefficienttwo = 0.0;
float coefficientthree = 0.0;
float coefficientfour = 0.0;
float coefficientfive = 0.0;
float coefficientsix = 0.0;
float coefficientseven = 0.0;
float coefficienteight = 0.0;
float coefficientnine = 0.0;
for (int i = 0; i< count; i++){
coefficientone = coefficientone + coeff[i];
coefficienttwo = coefficienttwo + coefftwo[i];
coefficientthree = coefficientthree + coeffthree[i];
coefficientfour = coefficientfour + coefffour[i];
coefficientfive = coefficientfive + coefffive[i];
coefficientsix = coefficientsix + coeffsix[i];
coefficientseven = coefficientseven + coeffseven[i];
coefficienteight = coefficienteight + coeffeight[i];
coefficientnine = coefficientnine + coeffnine[i];
}
printf("coefficient 1 = %f\n", coefficientone);
printf("coefficient 2 = %f\n", coefficienttwo);
printf("coefficient 3 = %f\n", coefficientthree);
printf("coefficient 4 = %f\n", coefficientfour);
printf("coefficient 5 = %f\n", coefficientfive);
printf("coefficient 6 = %f\n", coefficientsix);
printf("coefficient 7 = %f\n", coefficientseven);
printf("coefficient 8 = %f\n", coefficienteight);
printf("coefficient 9 = %f\n", coefficientnine);
}
Your algebra is simply wrong, and that fact is hidden by poorly chosen variable names.
When you calculate the contribution of the ith basis polynomial (never mind y for now) what variable represents the coefficient of the x2 term? It's coeff3. And you don't calculate it correctly.
Take a simpler case. Suppose you want to work out (x+a)(x+b)(x+c)(x+d). The first term is x4, easy. The next is (a+b+c+d)x3, not too bad. The next is (ab + ac + ad + bc + bd + cd)x2, and now it's clear that a single loop won't do the job. It's worth taking the time to make sure you can write code that handles the simple problem correctly, before you try the more complex one. You need something like this:
for(unsigned int j=0 ; j<count ; ++j)
{
...
coeff2 -= x[j];
for(unsigned int k=j ; k<count ; ++k)
{
if(j!=k && k!=i)
coeff3 += x[j] * x[k];
...
}
}
That should be enough to get you started.
I want to implement cryptography algorithms. So I need a suitable data type to handle integers with a lot of digits.
Many recent languages, such as Java, Python and Ruby provide native ways to do this. However, I'm programming in C, and I was wondering what is the best way and easiest way to implement elementary operations there.
I would like to write it without any external library. I thought about two options:
Using an array of char (like strings, that would be good for encryption/decryption keys)
Using an array of bits (I don't know how to do it, but I think this would be compiler-dependant)
What would you do?
The (to me) obvious choice would be GMP whose main developer, Torbjörn Granlund, was a member of the Swedish five man team that won the Simon Singh "Cipher Challenge" in 2000.
According to the website the code can be used to calculate 1000000000 digits of pi in 1957 seconds on an AMD Phenom II # 3.2 GHz.
The code has been developed since 1991.
I would first off highly suggest using an already existing library.
However, I have done this before in the past as an experiment. I choose option 2. Representing a value like "10000000002000000000" as
int array[2] = { 1000000000, 2000000000 }
and performing operations and carry values one int at a time. Not very efficient, but functionally sound.
If you are interested in Cryptography, then everything has to be correct. Either you spend many months writing and testing and testing and testing... your own big number arithmetic functions, or you use an existing library.
It is difficult enough getting crypto to work correctly when you know that the methods you are using are correct. It is almost impossible if the methods you are using have subtle errors.
For crypto use GMP, and concentrate on the crypto.
If you want to write your own large number arithmetic package, then by all means do so. I have done the same myself and it is an interesting and useful experience. But don't use your own work for anything critical.
It will be easier to deal with an array of characters. Its a good idea to devise your own class (/datatype), defining functions to deal with the all arithmetic operations for future use. You could use this one designed by ACRush for reference.
the variable in main function can Store even 100 factorial in c++
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <map>
#include <functional>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <stack>
#include <queue>
#include <deque>
#include <limits>
#include <cmath>
#include <numeric>
#include <set>
using namespace std;
//template for BIGINIT
// base and base_digits must be consistent
const int base = 10;
const int base_digits = 1;
struct bigint {
vector<int> a;
int sign;
bigint() :
sign(1) {
}
bigint(long long v) {
*this = v;
}
bigint(const string &s) {
read(s);
}
void operator=(const bigint &v) {
sign = v.sign;
a = v.a;
}
void operator=(long long v) {
sign = 1;
if (v < 0)
sign = -1, v = -v;
for (; v > 0; v = v / base)
a.push_back(v % base);
}
bigint operator+(const bigint &v) const {
if (sign == v.sign) {
bigint res = v;
for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) {
if (i == (int) res.a.size())
res.a.push_back(0);
res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
carry = res.a[i] >= base;
if (carry)
res.a[i] -= base;
}
return res;
}
return *this - (-v);
}
bigint operator-(const bigint &v) const {
if (sign == v.sign) {
if (abs() >= v.abs()) {
bigint res = *this;
for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
carry = res.a[i] < 0;
if (carry)
res.a[i] += base;
}
res.trim();
return res;
}
return -(v - *this);
}
return *this + (-v);
}
void operator*=(int v) {
if (v < 0)
sign = -sign, v = -v;
for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
if (i == (int) a.size())
a.push_back(0);
long long cur = a[i] * (long long) v + carry;
carry = (int) (cur / base);
a[i] = (int) (cur % base);
//asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
}
trim();
}
bigint operator*(int v) const {
bigint res = *this;
res *= v;
return res;
}
friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
int norm = base / (b1.a.back() + 1);
bigint a = a1.abs() * norm;
bigint b = b1.abs() * norm;
bigint q, r;
q.a.resize(a.a.size());
for (int i = a.a.size() - 1; i >= 0; i--) {
r *= base;
r += a.a[i];
int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
int d = ((long long) base * s1 + s2) / b.a.back();
r -= b * d;
while (r < 0)
r += b, --d;
q.a[i] = d;
}
q.sign = a1.sign * b1.sign;
r.sign = a1.sign;
q.trim();
r.trim();
return make_pair(q, r / norm);
}
bigint operator/(const bigint &v) const {
return divmod(*this, v).first;
}
bigint operator%(const bigint &v) const {
return divmod(*this, v).second;
}
void operator/=(int v) {
if (v < 0)
sign = -sign, v = -v;
for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
long long cur = a[i] + rem * (long long) base;
a[i] = (int) (cur / v);
rem = (int) (cur % v);
}
trim();
}
bigint operator/(int v) const {
bigint res = *this;
res /= v;
return res;
}
int operator%(int v) const {
if (v < 0)
v = -v;
int m = 0;
for (int i = a.size() - 1; i >= 0; --i)
m = (a[i] + m * (long long) base) % v;
return m * sign;
}
void operator+=(const bigint &v) {
*this = *this + v;
}
void operator-=(const bigint &v) {
*this = *this - v;
}
void operator*=(const bigint &v) {
*this = *this * v;
}
void operator/=(const bigint &v) {
*this = *this / v;
}
bool operator<(const bigint &v) const {
if (sign != v.sign)
return sign < v.sign;
if (a.size() != v.a.size())
return a.size() * sign < v.a.size() * v.sign;
for (int i = a.size() - 1; i >= 0; i--)
if (a[i] != v.a[i])
return a[i] * sign < v.a[i] * sign;
return false;
}
bool operator>(const bigint &v) const {
return v < *this;
}
bool operator<=(const bigint &v) const {
return !(v < *this);
}
bool operator>=(const bigint &v) const {
return !(*this < v);
}
bool operator==(const bigint &v) const {
return !(*this < v) && !(v < *this);
}
bool operator!=(const bigint &v) const {
return *this < v || v < *this;
}
void trim() {
while (!a.empty() && !a.back())
a.pop_back();
if (a.empty())
sign = 1;
}
bool isZero() const {
return a.empty() || (a.size() == 1 && !a[0]);
}
bigint operator-() const {
bigint res = *this;
res.sign = -sign;
return res;
}
bigint abs() const {
bigint res = *this;
res.sign *= res.sign;
return res;
}
long long longValue() const {
long long res = 0;
for (int i = a.size() - 1; i >= 0; i--)
res = res * base + a[i];
return res * sign;
}
friend bigint gcd(const bigint &a, const bigint &b) {
return b.isZero() ? a : gcd(b, a % b);
}
friend bigint lcm(const bigint &a, const bigint &b) {
return a / gcd(a, b) * b;
}
void read(const string &s) {
sign = 1;
a.clear();
int pos = 0;
while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
if (s[pos] == '-')
sign = -sign;
++pos;
}
for (int i = s.size() - 1; i >= pos; i -= base_digits) {
int x = 0;
for (int j = max(pos, i - base_digits + 1); j <= i; j++)
x = x * 10 + s[j] - '0';
a.push_back(x);
}
trim();
}
friend istream& operator>>(istream &stream, bigint &v) {
string s;
stream >> s;
v.read(s);
return stream;
}
friend ostream& operator<<(ostream &stream, const bigint &v) {
if (v.sign == -1)
stream << '-';
stream << (v.a.empty() ? 0 : v.a.back());
for (int i = (int) v.a.size() - 2; i >= 0; --i)
stream << setw(base_digits) << setfill('0') << v.a[i];
return stream;
}
static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
vector<long long> p(max(old_digits, new_digits) + 1);
p[0] = 1;
for (int i = 1; i < (int) p.size(); i++)
p[i] = p[i - 1] * 10;
vector<int> res;
long long cur = 0;
int cur_digits = 0;
for (int i = 0; i < (int) a.size(); i++) {
cur += a[i] * p[cur_digits];
cur_digits += old_digits;
while (cur_digits >= new_digits) {
res.push_back(int(cur % p[new_digits]));
cur /= p[new_digits];
cur_digits -= new_digits;
}
}
res.push_back((int) cur);
while (!res.empty() && !res.back())
res.pop_back();
return res;
}
typedef vector<long long> vll;
static vll karatsubaMultiply(const vll &a, const vll &b) {
int n = a.size();
vll res(n + n);
if (n <= 32) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
res[i + j] += a[i] * b[j];
return res;
}
int k = n >> 1;
vll a1(a.begin(), a.begin() + k);
vll a2(a.begin() + k, a.end());
vll b1(b.begin(), b.begin() + k);
vll b2(b.begin() + k, b.end());
vll a1b1 = karatsubaMultiply(a1, b1);
vll a2b2 = karatsubaMultiply(a2, b2);
for (int i = 0; i < k; i++)
a2[i] += a1[i];
for (int i = 0; i < k; i++)
b2[i] += b1[i];
vll r = karatsubaMultiply(a2, b2);
for (int i = 0; i < (int) a1b1.size(); i++)
r[i] -= a1b1[i];
for (int i = 0; i < (int) a2b2.size(); i++)
r[i] -= a2b2[i];
for (int i = 0; i < (int) r.size(); i++)
res[i + k] += r[i];
for (int i = 0; i < (int) a1b1.size(); i++)
res[i] += a1b1[i];
for (int i = 0; i < (int) a2b2.size(); i++)
res[i + n] += a2b2[i];
return res;
}
bigint operator*(const bigint &v) const {
vector<int> a6 = convert_base(this->a, base_digits, 6);
vector<int> b6 = convert_base(v.a, base_digits, 6);
vll a(a6.begin(), a6.end());
vll b(b6.begin(), b6.end());
while (a.size() < b.size())
a.push_back(0);
while (b.size() < a.size())
b.push_back(0);
while (a.size() & (a.size() - 1))
a.push_back(0), b.push_back(0);
vll c = karatsubaMultiply(a, b);
bigint res;
res.sign = sign * v.sign;
for (int i = 0, carry = 0; i < (int) c.size(); i++) {
long long cur = c[i] + carry;
res.a.push_back((int) (cur % 1000000));
carry = (int) (cur / 1000000);
}
res.a = convert_base(res.a, 6, base_digits);
res.trim();
return res;
}
};
//use : bigint var;
//template for biginit over
int main()
{
bigint var=10909000890789;
cout<<var;
return 0;
}