C: LU Complete Pivoting Decomposition and Matrix Solver; Something isn't right - c

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 )

Related

How to scale .pnm images in C?

so first off to give some background info I'm extremely new to C, currently learning it in university, and we had a lab last week that I was unable to attend and now I'm playing catch up trying to figure out how to do it without having been there when they explained it (They released a document of course explaining the assignment I just missed any extra verbal info they didn't include in the doc)
The lab assignment is that we are given an .pnm image file and have to scale it down by 1/2 (it will be 1/2 as wide and 1/2 as long).
I've gotten SOMETHING down to start but don't really know where to go from here. Any help would be appreciated.
For reference, here are are my functions in no particular order:
void fillImageArray(rgb_t *pixels, int max){
for(int a = 0; a < max; a++){
fscanf(stdin, "%i", &pixels[a].r);
fscanf(stdin, "%i", &pixels[a].g);
fscanf(stdin, "%i", &pixels[a].b);
}
}
#include "defs.h"
info_t getHeader(){
info_t header;
fscanf(stdin, "%s", &header.type);
int *z;
z = (int *) malloc(3 * sizeof(int));
for(int i = 0; i < 3; i++){
fscanf(stdin, "%i", &z[i]);
}
header.width = z[0];
header.height = z[1];
header.maxColor = z[2];
free(z);
return header;
}
#include"defs.h"
void writeHeader(info_t headerInfo){
fprintf(stdout, "%s\n", headerInfo.type);
fprintf(stdout, "%i %i %i\n", (headerInfo.width/2), (headerInfo.height/2), headerInfo.maxColor);
}
#include"defs.h"
void halfSizeWritePixels(rgb_t *pixels, int max){
for(int b = 0; b < max; b+=4){
fprintf(stdout, "%i ", pixels[b].r);
fprintf(stdout, "%i ", pixels[b].g);
fprintf(stdout, "%i\n", pixels[b].b);
}
}
Also, for reference, here is my header file:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//header struct
typedef struct info{
char type[3];
int width;
int height;
int maxColor;
}info_t;
//struct to hold pixels
typedef struct rgb{
unsigned int r;
unsigned int g;
unsigned int b;
}rgb_t;
//function prototypes
info_t getHeader();
void writeHeader(info_t headerInfo);
void fillImageArray(rgb_t *pixels, int max);
void writePixels(rgb_t *pixels, int max);
void halfSizeWritePixels(rgb_t *pixels, int max);
And here is my driver code:
#include"defs.h"
int main (){
//declaring header struct
info_t headerInfo;
//function to get header
headerInfo = getHeader();
int max = (headerInfo.width)*(headerInfo.height);
int max2 = max*3;
rgb_t *pixels;
pixels = (rgb_t *) malloc(max2 * sizeof(int));
//function to fill array
fillImageArray(pixels, max);
writeHeader(headerInfo);
//function to print image
halfSizeWritePixels(pixels, max);
free(pixels);
//end of program
return 0;
}
The way I was thinking of doing this is to read in the pixels from the file, which I know for a fact it does successfully, and then just output every 4th pixel, since when scaling the image by 1/2 it's reducing the amount of pixels overall by 1/4th.
**Here is the image we are given to start: https://i.stack.imgur.com/ukiw1.png
And here is what is outputted when I run my program: https://i.stack.imgur.com/dOU1W.png**
This lab is just building on our previous one (which I did successfully) - the previous lab assignment was to just make a program that can read in the .pnm file and output it, so I know that at least works.
This program is the the same as that one, with the only real change I made so far being changing this:
#include"defs.h"
void halfSizeWritePixels(rgb_t *pixels, int max){
for(int b = 0; b < max/4; b++){
fprintf(stdout, "%i ", pixels[b].r);
fprintf(stdout, "%i ", pixels[b].g);
fprintf(stdout, "%i\n", pixels[b].b);
}
}
To this:
#include"defs.h"
void halfSizeWritePixels(rgb_t *pixels, int max){
for(int b = 0; b < max/4; b+=4){
fprintf(stdout, "%i ", pixels[b].r);
fprintf(stdout, "%i ", pixels[b].g);
fprintf(stdout, "%i\n", pixels[b].b);
}
}
I know I haven't done much so far, but the logic of this makes sense to me. I've tried other slight variations of this and they all just crop the picture in different ways instead of scaling the entire thing down as a whole. Just not sure where to go from here since my logic is obviously flawed.
Again, any help would be greatly appreciated, I apologize in advance if this is a bit too general, I tried to be as specific as I reasonably could. Big thanks in advance to anyone who tries to help out.
b += 4 skips 3 out of every 4 pixels. You don't want that. You can see the result is that your output combines two rows of data in each row.
Think about it: For half-sized output you need to skip only every second pixel. But also you need to skip every second row of pixels. You cannot do this with your function as currently written, because it does not understand the image dimensions. The basic approach is:
for (int y = 0; y < height; y += 2) {
for (int x = 0; x < height; x += 2) {
int index = y * width + x;
// Write out the value of pixels[index]
}
}

program.exe (C) has stopped working

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.

Creating n random points and creating quadrilaterals (stuck) C

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)

quadratic Sum of N nummbers: implementation in C

As you can read in the header it is about a rather simple topic. But I encountered something very odd while implementing possible different ways to get a quadratic sum of N numbers.
I implemented three different versions:
Quadratic Gauß sum (func: quadratGauss(int n) )
Iterative (func: quadratIterativeClassic(int n) )
Iterative via Bitoperation (func: quadratIterativeBitoperation(int n) )
All three functions have returned the same result as expected from the given Input. The Big question now is. How was it possible for the third function to work proper? The Code looks like this:
void quadratGauss(int n){
printf("+quadratGauss: \n");
int result = ((n*(n+1))*(2*n+1))/2;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativClassic(int n){
int result;
printf("+quadratIterativClassic: \n");
for(int i;i<=n;i++)
result += i * i;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativeBitOperation(int n){
int result;
printf("+quadratIterativeBitOperation: \n");
for(int i;i<=n;i++)
result += i^2;
printf("Result: %d\n----------------\n",result);
}
As you see I use the XOR operator. I originally wanted to use the shift-operator "<<" but i tried others as well. what where stunning when i tried the XOR operator: the result was still the same as before and the same as the other two functions. I thought this was not possible because the XOR is not an operator for the power-operation because C does not contain such an operator but still i got eventually the right result.
I tested the functions with different numbers of different "sizes". Nothing odd in the result of each function.
I've got no clue why. But there must be an explanation, doesn't it?
If you have one, I would appreciate alot the effort of writing down a possible reason, why you can implement this with the XOR operator.
here the whole main file:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#define N 5000
void sumGauss(int n)
{
printf("+sumGauss: \n");
int result = (n*(n+1)/2);
printf("Result: %d\n----------------\n",result);
}
void sumClassic(int n)
{
printf("+sumClassic: \n");
int result = 0;
for(int i = 0; i <= n; i++)
result += i;
printf("Result: %d\n----------------\n",result);
}
void quadratGauss(int n){
printf("+quadratGauss: \n");
int result = ((n*(n+1))*(2*n+1))/2;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativeBitOperation(int n){
int result;
printf("+quadratIterativeBitOperation: \n");
for(int i;i<=n;i++)
result += i^2;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativClassic(int n){
int result;
printf("+quadratIterativClassic: \n");
for(int i;i<=n;i++)
result += i * i;
printf("Result: %d\n----------------\n",result);
}
void unevenSum(int n)
{
printf("+unevenSum: \n");
int uneven = 0;
int i=0;
for(i=1;i<= n;i+=2) {
uneven += i;
}
printf("Result: %d\n----------------\n",uneven*2);
}
void unevenSumModulo(int n)
{
printf("+unevenSumModulo: \n");
int result=0;
for(int i=0;i<=n;i++)
{
if( (i%1) == 0)
result += i;
}
printf("Result: %d\n----------------\n",result);
}
void unevenSumNico(int n)
{
printf("+unevenSumNico: \n");
int odd = 0;
int i=0;
for(i=1;i<= n;i++) {
odd += ((2*i)-1)/2;
}
printf("Result: %d\n----------------\n",odd);
}
void evenSum(int n)
{
printf("+evenSum: \n");
int result=0;
for(int i=0;i<=n;i++)
{
if( (i%2) == 0)
result += i;
}
printf("Result: %d\n----------------\n",result);
}
void Zins(float Kapital,int years)
{
printf("Zinstabelle fuer Grundkaptial %.2f Euro\n",Kapital);
printf("Kapitalstand zum Jahresende\n");
int i=0;
float K = Kapital;
for(int i =1;i<years+1;i++)
{
K = K *(1.f + 0.05f);
printf("Jahr: %2d Kapital: %.2f Euro\n",i,K);
}
}
int main(int argc, char** argv) {
sumGauss(N);
sumClassic(N);
quadratGauss(N);
quadratIterativeBitOperation(N);
quadratIterativClassic(N);
unevenSum(N);
unevenSumNico(N);
unevenSumModulo(N);
evenSum(N);
Zins(N);
return 0;
}
This would only be true for n = 0. Rest assured that you cannot implement squaring using just the XOR operator, even for integral types.
The behaviour of your code is currently undefined, as you don't initialise either i, or result. I suspect that your loop does not run at all and by the most amazing coincidence, result occupies the same memory in the subsequent functions as it does in the Guassian function. But don't ever rely on that behaviour. Other compilers might simply attempt to eat your cat.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char const *argv[]){
int i=0,n1;
scanf("%d",&n1);
void quadratGauss(int n){
printf("+quadratGauss: \n");
int result = ((n*(n+1))*(2*n+1))/6; // you made here mistake take 2 insted of 6.
printf("Result: %d\n----------------\n",result);
}
void quadratIterativClassic(int n){
int result=0;
printf("+quadratIterativClassic: \n");
for(i=1;i<=n;i++)
result += i * i;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativeBitOperation(int n){
int result=0;
printf("+quadratIterativeBitOperation: \n");
for(i=1;i<=n;i++)
result += pow(i,2); //This is power fun to add series of quadrat
printf("Result: %d\n----------------\n",result);
}
//call the fun.
quadratGauss(n1);
quadratIterativClassic(n1);
quadratIterativeBitOperation(n1);
return 0;
}
:) Want to more about http://www.trans4mind.com/personal_development/mathematics/series/sumNaturalSquares.htm
https://en.wikipedia.org/wiki/Quadratic_Gauss_sum
First, its /6, not /2. See that quadratGauss is always 3 times the quadratIterativClassic. And I got completely different results for quadratIterativeBitOperation
n = 4
+quadratGauss:
Result: 90
----------------
+quadratIterativClassic:
Result: 30
----------------
+quadratIterativeBitOperation:
Result: 12
----------------
n = 5
+quadratGauss:
Result: 165
----------------
+quadratIterativClassic:
Result: 55
----------------
+quadratIterativeBitOperation:
Result: 19
----------------
n = 6
+quadratGauss:
Result: 273
----------------
+quadratIterativClassic:
Result: 91
----------------
+quadratIterativeBitOperation:
Result: 23
I think it your compiler must have ^ set as exponent instead of XOR

Merging entries of two arrays as the even and odd entries of another array.

I've got a function thats able to produces 2 arrays, one when the index 'i' is even and one when the index 'i' is odd, so I end up with two arrays. The even 'i' array is called W_e and made of N elements, the odd 'i' array is called W_o and also made of N elements.
I now need to be merge these two arrays into another array Wn (which has 2*N elements) such that it looks like Wn=[W_e[0],W_o[0],W_e[1],W_o[1],...,W_e[N-1],W_o[N-1]] but I'm not sure how to do it. I tried to use nested loops but it didn't work. The arrays W_e and W_o are produced correctly according to my calculations, I'm just unable to combine the entries into one array.
This is what I have so far. I have not done anything in the main function except call the function which is giving me trouble "double *MakeWpowers(int N);". Please keep in mind this works for N>2, I have not yet dealt with N=1 or N=2.
Any help will be greatly appreciated. Thank you!!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
#define pi 4*atan(1)
double *MakeWpowers(int N);
void print_vector(double *x,int N);
double *make_vector(double *x,int N);
int main(void)
{ int N;
double *Wn;
printf("\n Please enter the size of the NxN matrix:\n");
scanf("%d",&N);
Wn=MakeWpowers(N);
//print_vector(Wn,N);
free(Wn);
return(0);
}
double *MakeWpowers(int N)
{
double *Wn,*W_e,*W_o;
int i,j;
Wn=make_vector(Wn, 2*N);
W_e=make_vector(W_e, N);
W_o=make_vector(W_o, N);
for(i=0;i<=N-1;i++)
{
if(i%2==0)
{
W_e[i]=cos((2*i*pi)/N);
}
else
{
W_o[i]=sin((2*i*pi)/N);
}
}
printf("\nThis is the even vector W_e:\n");
print_vector(W_e, N);
printf("\nThis is the odd vector W_o:\n");
print_vector(W_o, N);
for(j=0;j<2*N;j++)
{
if(j%2==0)
{Wn[j]=W_e[i];}
//++i;}
else
{Wn[j]=W_o[i];}
//++i;}
printf("\nthis is Wn:\n\n");
print_vector(Wn, 2*N);
//Wn[j]=W_o[i];
//j++;
}
return(Wn);
}
void print_vector(double *x,int N)
{
int i;
for (i=0; i<N; i++)
{
printf ("%9.4f \n", x[i]);
}
printf("\n");
}
double *make_vector(double *x,int N)
{ int i;
double xi;
x=(double *)malloc((N)*sizeof(double));
for(i=0;i<N;i++)
{
x[i]=(double)xi;
}
return(x);
}
Here's the general logic to it:
LET a, b, merge BE ARRAYS
FOR k IN 0..length(a)
merge[2*k] = a[i]
merge[2*k+1] = b[i]
RETURN merge
a makes the even entries (2k), b the odd ones (2k+1).
This is probably wrong
double *make_vector(double *x,int N)
{ int i;
double xi;
You have to initialize variable xi same thing goes for *Wn,*W_e,*W_o

Resources