I have this homework assignment and I am a bit stuck with it.
Create n random points, using these points create 2 quadrilaterals, which envelop the rest of the points, and compare the area of the 2 shapes.(not a graphical solution, purely mathematical)
I can not figure out how to connect my points or how to tell the computer which points to connect. I was thinking maybe finding the max and min X and Y could work but I didn't get further than that.
Thanks is advance!
void genp(int n,int** x,int** y);
void rectangle(int n,int** x,int** y);
void file(int n, int** x, int** y);
int main()
{
int n;
printf("Please specify number of points!\n");
scanf("%d", &n);
int *x;
int *y;
genp(n,&x,&y);
for (int i = 0; i < n; i++)
{
printf("x[%d]=%d\ty[%d]=%d\n", i, x[i], i, y[i]);
}
rectangle(n,&x,&y);
file(n,&x,&y);
free(x);
free(y);
return 0;
}
void genp(int n,int** x, int** y)
{
int r;
srand(time(NULL));
*x = (int*)malloc(n * sizeof(int));
*y = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
{
r = rand();
(*x)[i] = r;
r = rand();
(*y)[i] = r;
}
}
void rectangle(int n,int** x,int **y)
{
int maxlocx,maxlocy,maxx,maxy,minx,miny,minlocx,minlocy;
int zerox=*x[0];
int zeroy=*y[0];
for(int i=0;i<n;i++)
{
if ((*x)[i]>zerox)
{
maxx=(*x)[i];
maxlocx=i;
}
if ((*y)[i]>zeroy)
{
maxy=(*y)[i];
maxlocy=i;
}
}
for (int i=0;i<n;i++)
{
if ((*x)[i]<zerox)
{
minx=(*x)[i];
minlocx=i;
}
if ((*y)[i]<zeroy)
{
miny=(*y)[i];
minlocy=i;
}
}
printf("\nThe max x:%d, corresponding y:%d\n",maxx,(*y)[maxlocx]);
printf("\nThe max y:%d, corresponding x:%d\n",maxy,(*x)[maxlocy]);
printf("\nThe min x:%d, corresponding y:%d\n",minx,(*y)[minlocx]);
printf("\nThe min y:%d, corresponding x:%d\n",miny,(*x)[minlocy]);
int area=
}
void file(int n,int** x,int** y)
{
FILE *f;
f=fopen("data.txt","w");
fprintf(f,"n=%d\n",n);
for (int i=0;i<n;i++)
{
fprintf(f,"%d,%d\n",(*x)[i],(*y)[i]);
}
fclose(f);
}
I was thinking maybe finding the max and min X and Y could work but I didn't get further than that.
This sounds about right for me and was the first thing that I thought when reading that problem statement.
As for the 2nd quadrilateral maybe you could do something like trying to find a bounding rectangle with tilted axis instead of axis that are parellel to the X and Y axis. For example, with a tilt of 45 degrees the bounding box would look like this:
I can not figure out how to connect my points or how to tell the computer which points to connect.
I'm kind of getting the impression that you are trying to find the Convex Hull of your set of points. That would be a much harder problem than just finding a bounding box. (And it might not be a quadrilateral anyway)
Related
I need help solving this task, if anyone had a similar problem it would help me a lot.
The task is:
Write a program that calculates the degree and polynomial p(x) for a given x.
For example:
Enter n:2 //degree of polynomial and function degree
Enter x:2
x^n=4
Enter coefficients of polynomial:
a[0]=1
a[1]=2
a[2]=3
P(x)=3*x^2 + 2*x^1 +1*x^0 = 17
I did it like this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100
/*
*/
typedef struct polynomial {
double coef[MAX];
} POLYNOMIAL;
double degree(double ,int );
double px(POLYNOMIAL ,double );
int main()
{
POLYNOMIAL p;
double x,pom;
int n;
printf("Enter degree (n>=0):");
scanf("%d",&n);
while(n<1 || n>MAX)
{
printf("Enter degree (n>=0):");
scanf("%d",&n);
}
printf("Enter x:");
scanf("%lf",&x);
pom=degree(x,n);
printf("%.2lf^%d =%lf",x,n,pom);
printf("\nEnter coefficients of polynomial :\n");
for(int i=0;i<=n;i++)
{
printf("a[%d]:",i);
scanf("%lf",&p.coef[i]);
}
return 0;
}
double degree(double x,int n)
{
double degree=1;
if(n==0)
{
return 1;
}
for(int i=1;i<=n;i++)
{
degree*=x;
}
return degree;
}
double px(POLYNOMIAL p,double x)
{
double sum=0;
for(int j=0;j<"I don't know what to put here";j++)
{
sum+=(double)p.coef[j]*degree(x,j);
}
printf("%lf",sum);
}
The problem arises when calculating polynomials, because I don't know what to put as a condition in the for loop, there should be j < of the length of the array entered, that is, of degree n,
but n cannot be used as a parameter in the px function? The task must be done with the structure and functions listed.
Thanks in advance !
If you are not allowed to pass n to the function, you can instead just loop to MAX and make sure that all unused coefficients are zero.
In other words, just initialize all elements of p to zero
POLYNOMIAL p = {.coef = {0} };
and let the loop be:
j < MAX
BTW: Notice that you need return sum in the function.
Further the function degree is pretty unnecessary. Consider this:
double px(POLYNOMIAL p,double x)
{
double sum=p.coef[0];
double d = x;
for(int j=1;j<MAX;j++)
{
sum+=(double)p.coef[j]*d;
d = d * x;
}
printf("%lf",sum);
return sum;
}
#include <stdio.h>
#include <math.h>
typedef struct
{
int x,y;
}point;
double distance(point p1[], point p2[], int i)
{
double d = sqrt((pow(p2[i+1].x-p1[i].x,2)) + (pow(p2[i+1].y-p1[i].y,2)));
return d;
}
int main()
{
int size,i;
double d;
printf("Enter number of point: ");
scanf("%d",&size);
point p[size];
for(i=0;i<size;i++)
{
printf("Enter point %d: ",i+1);
scanf("%d,%d",&p[i].x,&p[i].y);
}
d = distance(p[0].x,p[0].y,0);
for(i=0;i<size-1;i++)
{
if( d > distance(p[i+1].x,p[i+1].y,i))
{
d = distance(p[i+1].x,p[i+1].y,i);
}
}
printf("Closest pair distance = %.4lf",d);
}
I have been trying to finish this homework for a while and I'm not sure on how to fix this.
The output supposed to look like this:
This is what I got:
First, I think your distance function should get two points, and not two points arrays. you also don't need to pass the index. this way your function will only do what it should do: calculate the Euclidean distance.
double distance(point p1, point p2)
{
double d = sqrt(pow(p2.x-p1.x,2) + pow(p2.y-p1.y,2));
return d;
}
Second, in your main function, do you want to check only the distance between consecutive points or between any point? I think you want the second option but decide for yourself:
first option:
for(i=0;i<size-1;i++)
{
if( d > distance(p[i],p[i+1]))
{
d = distance(p[i],p[i+1]);
}
}
second option:
for(i=0;i<size-1;i++)
{
for (j=i+1;j<size;j++)
{
if( d > distance(p[i],p[j]))
{
d = distance(p[i],p[j]);
}
}
}
notice I set j=i+1 because first, i don't want to calculate distance(p[i],p[i]) because that will always be 0 and that is the minimal value distance can return. secondly it's sufficient to test only for j>i values because distance(p[i],p[j])==distance(p[j],p[i])
I hope that cover everything
I have done some changes. Read the comments marked with // CHANGE HERE to understand the changes.
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
typedef struct
{
// CHANGE HERE: double instead of int
double x, y;
} point;
// CHANGE HERE: just accept two points whose distance needs to be calculated
double distance(point p1, point p2)
{
return sqrt((pow(p1.x - p2.x, 2)) + (pow(p1.y - p2.y, 2)));
}
int main()
{
int size, i, j;
double d;
printf("Enter number of points: ");
scanf("%d", &size);
// CHANGE HERE: use malloc for variable sized arrays
point* p = malloc(size * sizeof(point));
for (i = 0; i < size; i++)
{
// CHANGE HERE: read double instead of int
printf("Enter point %d: ", i + 1);
scanf("%lf,%lf", &p[i].x, &p[i].y);
}
// CHANGE HERE: store a high value by default
d = DBL_MAX;
for (i = 0; i < size - 1; i++)
{
// CHANGE HERE: to get the exact pair of points with closest distance
// you need to compare the distance of each point with the rest
for (j = i + 1; j < size; j++)
{
// CHANGE HERE: pass previous and current point to distance
double dist = distance(p[i], p[j]);
if (d > dist)
{
d = dist;
}
}
}
printf("Closest pair distance = %.4lf", d);
// CHANGE HERE: don't forget to free malloc()ed memory
free(p);
return 0;
}
As mentioned by #tstanisl, you can also use hypot function present in math.h, like:
double distance(point p1, point p2)
{
return hypot(p1.x - p2.x, p1.y - p2.y);
}
I'm trying to create a program that compares the efficiency of calculating a function through MacLaurin series.
The idea is: Make a graph (using gnuplot) of cos(x) between -Pi and Pi (100 intervals) calculating cos(x) using the first 4 terms of its MacLaurin series, then, the first 6 terms, and comparing the graph between them.
Cos(x) through MacLaurin.
So, to use gnuplot, I made the code below that gets 2 files with the data I need, however, when i run the code only the first result is correct. For the first 4 terms my file is:
-3.141593 -9.760222e-001
-3.078126 2.367934e+264
And the rest of what would be my Y axis is just 2.367934e+264 repeated over and over. The 6 terms file is also just that number. X axis is fine.
I'm fairly new to coding and just don't know what i'm doing wrong. Any help would be appreciated.
Here's the code:
#include <stdio.h>
#include <math.h>
#define X_INI -M_PI
#define X_FIM M_PI
#define NI 100
int fatorial(int);
double serie(int ,double );
int main()
{
double x, y[NI], dx;
int i;
FILE *fp[3];
fp[0]=fopen("4Termos.dat","w");
fp[1]=fopen("6Termos.dat","w");
x=X_INI;
dx = (X_FIM - X_INI)/ (NI - 1);
for(i=0; i<NI; i++){
y[i]=serie(4,x);
fprintf(fp[0],"%lf %e\n", x, y[i]);
y[i]=serie(6,x);
fprintf(fp[1],"%lf %e\n", x, y[i]);
x = x + dx;
}
return 0;
}
int fatorial(int n) {
int i,p;
p = 1;
if (n==0)
return 1;
else {
for (i=1;i<=n;i++)
p = p*i;
return p;
}
}
double serie(int m, double z){
double s;
int j;
for(j = 0; j < m+1; j++)
{
s = s + ( ( pow((-1) , j))*pow(z, (2*j)) ) / (fatorial(2*j));
}
return s;
}
Fatorial is used to calculate factorial, serie used to calculate MacLaurin...
Use of uninitialized s in serie() function (I've taken the liberty to format the code to my liking).
double serie(int m, double z) {
double s; // better: double s = 0;
int j;
for (j = 0; j < m + 1; j++) {
s += pow(-1, j) * pow(z, 2 * j) / fatorial(2 * j);
}
return s;
}
I am extremely new to C and managed to compile this program, but the exe stops working upon running. I'm really not sure what's wrong.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TINY 1.0e-20 // A small number.
void ludcmp(float a[3][3], int n, int *indx, float *d);
void lubksb(float a[3][3], int n, int *indx, float b[]) ;
int main(){
int i,n,*indx;
float *b,d;
float a[3][3] = {
{ 1.0, 2.0, 5.0},
{-1.0, 2.0, 3.0},
{ 6.0, 0.0, 1.0}
};
ludcmp(a,n,indx,&d);
lubksb(a,n,indx,b);
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
getchar();
return 0;
}
For those who were asking, the 2 functions ludcmp and lubksg are below. I got them from the numerical recipes textbook, but edited some lines to remove exclusive routines which I do not have. Specifically, they are the lines with malloc, printf, and free.
The original code came with all the loops starting with 1, which is why I also started my loop with 1. I have since changed all the loops to start from 0 instead, hopefully without introducing any new errors.
You can see the original code here:
https://github.com/saulwiggin/Numerical-Recipies-in-C/tree/master/Chapter2.Solution-of-Linear-Equations
Here is ludcmp:
void ludcmp(float a[3][3], int n, int *indx, float *d)
{
int i, imax, j, k;
float big, dum, sum, temp;
float *vv; // vv stores the implicit scaling of each row.
vv = (float *) malloc(n * sizeof(float));
*d=1.0;
for (i=0;i<n;i++) {
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0)
{
printf("Singular matrix in routine ludcmp");
//free(vv);
}
// No nonzero largest element.
vv[i] = 1.0 / big; // Save the scaling.
}
// This is the loop over columns of Crout's method.
for (j=0;j<n;j++) {
for (i=0;i<j;i++) {
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
// Initialize for the search for largest pivot element.
big=0.0;
for (i=j;i<=n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
} // Go back for the next column in the reduction.
free(vv);
}
And lubksb:
void lubksb(float a[3][3],int n,int *indx,float b[])
{
int i,ii=0,ip,j;
float sum;
for (i=1;i<=n;i++) {
ip=indx[i];
sum=b[ip];
b[ip]=b[i];
if (ii)
for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
else if (sum) ii=i;
b[i]=sum;
}
for (i=n;i>=1;i--) {
sum=b[i];
for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
b[i]=sum/a[i][i];
}
}
This is a Two Dimensional Array and you are looping as it was just one. You should do something like:
for (int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
printf("%d %d: ", i+1, j+1);
}
}
Is bad practice to define the size of the array explicit. Try to use a constant.
And as said in the comments by #Marged:
In C arrays starts in 0
b is never assigned to anything valid when it's declared:
float *b,d;
At best, it's NULL or pointing to an invalid memory address:
I don't know what the lubksb function does:
lubksb(a,n,indx,b);
But b is clearly an invalid parameter since you never assign to it before calling this function.
And with this statement:
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
As others have pointed out, array indices start at zero. But there's no evidence that b has a length of three anyway.
I've been working on a DIY linalg solver for a few days, and its coming together (no small things to you guys at stackexchange) But I'm currently experiencing a Brain Fart and can't see what's wrong with the current code. Any insights would be appreciated; you guys rock!
The below code should be copy-pastable; the results should be -15,8,2, but its currently pumping out 2,inf,-inf, which is, needless to say, incorrect.
EDIT: I think the last thing left to fix is the Back Substitution / Ux=x stage, but as far as I can tell this is 'correct'. I'm following through this example to check my intermediate working
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define MAT1 3
#define TINY 1e-20
#define a(i,j) a[(i)*MAT1+(j)]
void h_pivot_decomp(float *a, int *p, int *q){
int i,j,k;
int n=MAT1;
int pi,pj,tmp;
float max;
float ftmp;
for (k=0;k<n;k++){
pi=-1,pj=-1,max=0.0;
//find pivot in submatrix a(k:n,k:n)
for (i=k;i<n;i++) {
for (j=k;j<n;j++) {
if (fabs(a(i,j))>max){
max = fabs(a(i,j));
pi=i;
pj=j;
}
}
}
//Swap Row
tmp=p[k];
p[k]=p[pi];
p[pi]=tmp;
for (j=0;j<n;j++){
ftmp=a(k,j);
a(k,j)=a(pi,j);
a(pi,j)=ftmp;
}
//Swap Col
tmp=q[k];
q[k]=q[pj];
q[pj]=tmp;
for (i=0;i<n;i++){
ftmp=a(i,k);
a(i,k)=a(i,pj);
a(i,pj)=ftmp;
}
//END PIVOT
//check pivot size and decompose
if ((fabs(a(k,k))>TINY)){
for (i=k+1;i<n;i++){
//Column normalisation
ftmp=a(i,k)/=a(k,k);
for (j=k+1;j<n;j++){
//a(ik)*a(kj) subtracted from lower right submatrix elements
a(i,j)-=(ftmp*a(k,j));
}
}
}
//END DECOMPOSE
}
}
void h_solve(float *a, float *x, int *p, int *q){
//forward substitution; see Golub, Van Loan 96
//And see http://www.cs.rutgers.edu/~richter/cs510/completePivoting.pdf
int i,ii=0,ip,j,tmp;
float ftmp;
float xtmp[MAT1];
//Swap rows (x=Px)
puts("x=Px Stage");
for (i=0; i<MAT1; i++){
xtmp[i]=x[p[i]]; //value that should be here
printf("x:%.1lf,q:%d\n",xtmp[i],q[i]);
}
//Lx=x
puts("Lx=x Stage");
//I suspect this is where this is falling down, as my implementation
//uses the combined LU matrix, and this is using the non-unit diagonal
for (i=0;i<MAT1;i++){
ftmp=xtmp[i];
if (ii != 0)
for (j=ii-1;j<i;j++)
ftmp-=a(i,j)*xtmp[j];
else
if (ftmp!=0.0)
ii=i+1;
xtmp[i]=ftmp;
printf("x:%.1lf,q:%d\n",xtmp[i],q[i]);
}
puts("Ux=x");
//backward substitution
//partially taken from Sourcebook on Parallel Computing p577
//solves Uy=z
for (j=0;j<MAT1;j++){
xtmp[j]=xtmp[j]/a(j,j);
for (i=j+1;i<MAT1;i++){
xtmp[i]-=a(i,j)*xtmp[j];
}
printf("x:%.1lf,q:%d\n",xtmp[i],q[i]);
}
//Last bit
//solves x=Qy
puts("x=Qx Stage");
for (i=0;i<MAT1;i++){
x[i]=xtmp[p[i]];
printf("x:%.1lf,q:%d\n",x[i],q[i]);
}
}
void main(){
//3x3 Matrix
//float a[]={1,-2,3,2,-5,12,0,2,-10};
//float a[]={1,3,-2,3,5,6,2,4,3};
//float b[]={5,7,8};
//float a[]={1,2,3,2,-1,1,3,4,-1};
//float b[]={14,3,8};
float a[]={1,-2,1,0,2,2,-2,4,2};
float b[]={1,4,2};
int sig;
puts("Declared Stuff");
//pivot array (not used currently)
int* p_pivot = (int *)malloc(sizeof(int)*MAT1);
int* q_pivot = (int *)malloc(sizeof(int)*MAT1);
puts("Starting Stuff");
for (unsigned int i=0; i<MAT1; i++){
p_pivot[i]=i;
q_pivot[i]=i;
printf("%.1lf|",b[i]);
for (unsigned int j=0;j<MAT1; j++){
printf("%.1lf,",a(i,j));
}
printf("|%d,%d",p_pivot[i],q_pivot[i]);
puts("");
}
h_pivot_decomp(&a[0],p_pivot,q_pivot);
puts("After Pivot");
for (unsigned int i=0; i<MAT1; i++){
printf("%.1lf|",b[i]);
for (unsigned int j=0;j<MAT1; j++){
printf("%.1lf,",a(i,j));
}
printf("|%d,%d",p_pivot[i],q_pivot[i]);
puts("");
}
h_solve(&a[0],&b[0],p_pivot,q_pivot);
puts("Finished Solve");
for (unsigned int i=0; i<MAT1; i++){
printf("%.1lf|",b[i]);
for (unsigned int j=0;j<MAT1; j++){
printf("%.1lf,",a(i,j));
}
puts("");
}
}
Sorted; see here for full answers and code; there were too many small problems to itemise.
EDIT updated link (People still need this after 7 years?! :D )