Skip to content

Commit 7998183

Browse files
authored
Merge pull request algorithm-archivists#124 from Gathros/C_fixes
Fixing stable_marriage.c and convolutions.c
2 parents 2e7f37d + d64d2a1 commit 7998183

File tree

4 files changed

+133
-128
lines changed

4 files changed

+133
-128
lines changed

chapters/convolutions/code/c/convolutions.c

+4-43
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,9 @@
1-
#include <stdio.h>
2-
#include <complex.h>
3-
4-
// This section is not a part of the algorithm
5-
6-
#include <math.h>
1+
#include "fft.h"
72

8-
void fft(double complex *X, size_t N) {
9-
if (N >= 2) {
10-
double complex tmp [N / 2];
11-
for (size_t i = 0; i < N / 2; ++i) {
12-
tmp[i] = X[2 * i + 1];
13-
X[i] = X[2 * i];
14-
}
15-
16-
for (size_t i = 0; i < N / 2; ++i) {
17-
X[i + N / 2] = tmp[i];
18-
}
19-
20-
fft(X, N / 2);
21-
fft(X + N / 2, N / 2);
22-
23-
for (size_t i = 0; i < N / 2; ++i) {
24-
X[i + N/2] = X[i] - cexp(-2.0 * I * M_PI * i / N) * X[i + N / 2];
25-
X[i] -= (X[i + N / 2] - X[i]);
26-
}
27-
}
28-
}
29-
30-
void ifft(double complex *x, size_t n) {
31-
for (size_t i = 0; i < n; ++i) {
32-
x[i] = conj(x[i]);
33-
}
34-
35-
fft(x, n);
36-
37-
for (size_t i = 0; i < n; ++i) {
38-
x[i] = conj(x[i]) / n;
39-
}
40-
}
41-
42-
// This section is a part of the algorithm
3+
#include <stdio.h>
434

445
void conv(double complex *signal1, double complex *signal2, double complex* out,
45-
size_t n1, size_t n2) {
6+
size_t n1, size_t n2) {
467
double complex sum = 0;
478

489
for (size_t i = 0; i < (n1 < n2? n2 : n1); ++i) {
@@ -57,7 +18,7 @@ void conv(double complex *signal1, double complex *signal2, double complex* out,
5718
}
5819

5920
void conv_fft(double complex *signal1, double complex *signal2,
60-
double complex* out, size_t n) {
21+
double complex* out, size_t n) {
6122
fft(signal1, n);
6223
fft(signal2, n);
6324

chapters/convolutions/code/c/fft.h

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifndef FFT_H
2+
#define FFT_H
3+
4+
#include <complex.h>
5+
#include <math.h>
6+
7+
void fft(double complex *X, size_t N) {
8+
if (N >= 2) {
9+
double complex tmp [N / 2];
10+
for (size_t i = 0; i < N / 2; ++i) {
11+
tmp[i] = X[2 * i + 1];
12+
X[i] = X[2 * i];
13+
}
14+
15+
for (size_t i = 0; i < N / 2; ++i) {
16+
X[i + N / 2] = tmp[i];
17+
}
18+
19+
fft(X, N / 2);
20+
fft(X + N / 2, N / 2);
21+
22+
for (size_t i = 0; i < N / 2; ++i) {
23+
X[i + N/2] = X[i] - cexp(-2.0 * I * M_PI * i / N) * X[i + N / 2];
24+
X[i] -= (X[i + N / 2] - X[i]);
25+
}
26+
}
27+
}
28+
29+
void ifft(double complex *x, size_t n) {
30+
for (size_t i = 0; i < n; ++i) {
31+
x[i] = conj(x[i]);
32+
}
33+
34+
fft(x, n);
35+
36+
for (size_t i = 0; i < n; ++i) {
37+
x[i] = conj(x[i]) / n;
38+
}
39+
}
40+
41+
#endif //FFT_H

chapters/convolutions/convolutions.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ In code, this looks something like:
4141
{% sample lang="hs" %}
4242
[import:1-5, lang:"haskell"](code/haskell/convolution.hs)
4343
{% sample lang="c"%}
44-
[import:44-57, lang:"c_cpp"](code/c/convolutions.c)
44+
[import:5-18, lang:"c_cpp"](code/c/convolutions.c)
4545
{% sample lang="cpp"%}
4646
[import:68-88, lang:"c_cpp"](code/c++/convolutions.cpp)
4747
{% endmethod %}
@@ -90,7 +90,7 @@ The FFT-based convolution in Haskell is complicated, so here is some simple juli
9090
[import:19-22, lang:"julia"](code/julia/conv.jl)
9191
Where the `.*` operator is an element-wise multiplication.
9292
{% sample lang="c"%}
93-
[import:59-69, lang:"c_cpp"](code/c/convolutions.c)
93+
[import:20-30, lang:"c_cpp"](code/c/convolutions.c)
9494
{% sample lang="cpp"%}
9595
[import:90-105, lang:"c_cpp"](code/c++/convolutions.cpp)
9696
{% endmethod %}
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,121 @@
1+
#include <stdbool.h>
12
#include <stdio.h>
23
#include <stdlib.h>
3-
#include <stdbool.h>
4+
#include <string.h>
5+
#include <time.h>
6+
7+
struct person {
8+
int id;
9+
struct person *partner;
10+
size_t *prefers;
11+
size_t index;
12+
};
13+
14+
void shuffle(size_t *array, size_t size) {
15+
for (size_t i = size - 1; i > 0; --i) {
16+
size_t j = rand() % (i + 1);
17+
size_t tmp = array[i];
18+
array[i] = array[j];
19+
array[j] = tmp;
20+
}
21+
}
22+
23+
void create_group(struct person *group, size_t size, bool are_men) {
24+
for (size_t i = 0; i < size; ++i) {
25+
group[i].id = i;
26+
group[i].partner = NULL;
27+
group[i].prefers = (size_t*)malloc(sizeof(size_t) * size);
28+
group[i].index = 0;
429

5-
typedef struct person {
6-
size_t id;
7-
size_t prtnr;
8-
size_t *prefs;
9-
size_t pref_ind;
10-
} person;
11-
12-
void shuffle(size_t *x, size_t n) {
13-
if (n > 1) {
14-
for (size_t i = 0; i < n - 1; ++i) {
15-
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
16-
size_t t = x[j];
17-
x[j] = x[i];
18-
x[i] = t;
30+
for (size_t j = 0; j < size; ++j) {
31+
group[i].prefers[j] = j;
1932
}
33+
34+
shuffle(group[i].prefers, size);
2035
}
2136
}
2237

23-
bool prefers(size_t *prefs, size_t prtnr_id, size_t prop_id, size_t pref_size) {
24-
for (size_t i = 0; i < pref_size; ++i) {
25-
if (prefs[i] == prtnr_id) {
26-
return false;
27-
} else if(prefs[i] == prop_id) {
38+
bool prefers_partner(size_t *prefers, size_t partner, size_t id, size_t size) {
39+
for (size_t i = 0; i < size; ++i) {
40+
if (prefers[i] == partner) {
2841
return true;
42+
} else if(prefers[i] == id) {
43+
return false;
2944
}
3045
}
3146
}
3247

33-
void create_ppl(person *grp, size_t grp_size) {
34-
for (size_t i = 0; i < grp_size; ++i) {
35-
person prn;
36-
prn.id = i;
37-
prn.prtnr = grp_size + 1;
38-
prn.pref_ind = 0;
39-
prn.prefs = (size_t *) malloc(sizeof(size_t) * grp_size);
40-
41-
for (size_t j = 0; j < grp_size; ++j) {
42-
prn.prefs[j] = j;
43-
}
48+
void stable_marriage(struct person *men, struct person *women, size_t size) {
49+
struct person *bachelors[size];
50+
size_t bachelors_size = size;
4451

45-
shuffle(prn.prefs, grp_size);
46-
grp[i] = prn;
52+
for (size_t i = 0; i < size; ++i) {
53+
bachelors[i] = &men[i];
4754
}
48-
}
49-
50-
void stable_matching(person *men, person *women, size_t grp_size) {
51-
bool cont = true;
52-
while (cont) {
53-
for (size_t i = 0; i < grp_size; ++i) {
54-
if (men[i].prtnr == (grp_size + 1)) {
55-
size_t wmn_id = men[i].prefs[men[i].pref_ind];
56-
57-
if (women[wmn_id].prtnr == (grp_size + 1)) {
58-
men[i].prtnr = wmn_id;
59-
women[wmn_id].prtnr = i;
60-
} else if(prefers(women[wmn_id].prefs, women[wmn_id].prtnr, i,
61-
grp_size)) {
62-
men[women[wmn_id].prtnr].prtnr = grp_size + 1;
63-
women[wmn_id].prtnr = i;
64-
men[i].prtnr = wmn_id;
65-
}
66-
67-
men[i].pref_ind++;
68-
}
69-
}
7055

71-
cont = false;
72-
for (size_t i = 0; i < grp_size; ++i) {
73-
if (men[i].prtnr == (grp_size + 1)) {
74-
cont = true;
75-
break;
76-
}
56+
while (bachelors_size > 0) {
57+
struct person *man = bachelors[bachelors_size - 1];
58+
struct person *woman = &women[man->prefers[man->index]];
59+
60+
if (!woman->partner) {
61+
woman->partner = man;
62+
man->partner = woman;
63+
bachelors[--bachelors_size] = NULL;
64+
} else if (!prefers_partner(woman->prefers, woman->partner->id, man->id,
65+
size)) {
66+
67+
woman->partner->index++;
68+
bachelors[bachelors_size - 1] = woman->partner;
69+
woman->partner = man;
70+
man->partner = woman;
71+
} else {
72+
man->index++;
7773
}
7874
}
7975
}
8076

81-
void kill(person *grp, size_t grp_size) {
82-
for (size_t i = 0; i < grp_size; ++i) {
83-
free(grp[i].prefs);
77+
void free_group(struct person *group, size_t size) {
78+
for (size_t i = 0; i < size; ++i) {
79+
free(group[i].prefers);
8480
}
8581
}
8682

8783
int main() {
88-
int grp_size = 5;
89-
person men[grp_size], women[grp_size];
84+
srand(time(NULL));
9085

91-
create_ppl(men, grp_size);
92-
create_ppl(women, grp_size);
86+
struct person men[5], women[5];
9387

94-
stable_matching(men, women, grp_size);
88+
create_group(men, 5, true);
89+
create_group(women, 5, false);
9590

96-
for (size_t i = 0; i < grp_size; ++i) {
97-
printf("preferences of man %zu \n", i);
98-
for (size_t j = 0; j < grp_size; ++j) {
99-
printf("%zu \n", men[i].prefs[j]);
91+
for (size_t i = 0; i < 5; ++i) {
92+
printf("preferences of man %zu: ", i);
93+
for (size_t j = 0; j < 5; ++j) {
94+
printf("%zu ", men[i].prefers[j]);
10095
}
96+
97+
printf("\n");
10198
}
10299

103-
for (size_t i = 0; i < grp_size; ++i) {
104-
printf("preferences of woman %zu \n", i);
105-
for (size_t j = 0; j < grp_size; ++j) {
106-
printf("%zu \n", women[i].prefs[j]);
100+
printf("\n");
101+
102+
for (size_t i = 0; i < 5; ++i) {
103+
printf("preferences of woman %zu: ", i);
104+
for (size_t j = 0; j < 5; ++j) {
105+
printf("%zu ", women[i].prefers[j]);
107106
}
108-
}
109107

110-
for (size_t i = 0; i < grp_size; ++i) {
111-
printf("partners of man %zu is woman %zu\n", i, men[i].prtnr);
108+
printf("\n");
112109
}
113110

114-
kill(men, grp_size);
115-
kill(women, grp_size);
111+
stable_marriage(men, women, 5);
112+
113+
printf("\n");
114+
115+
for (size_t i = 0; i < 5; ++i) {
116+
printf("the partner of man %zu is woman %d\n", i, men[i].partner->id);
117+
}
116118

117-
return 0;
119+
free_group(men, 5);
120+
free_group(women, 5);
118121
}

0 commit comments

Comments
 (0)