Skip to content

Fixing stable_marriage.c and convolutions.c #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 4 additions & 43 deletions chapters/convolutions/code/c/convolutions.c
Original file line number Diff line number Diff line change
@@ -1,48 +1,9 @@
#include <stdio.h>
#include <complex.h>

// This section is not a part of the algorithm

#include <math.h>
#include "fft.h"

void fft(double complex *X, size_t N) {
if (N >= 2) {
double complex tmp [N / 2];
for (size_t i = 0; i < N / 2; ++i) {
tmp[i] = X[2 * i + 1];
X[i] = X[2 * i];
}

for (size_t i = 0; i < N / 2; ++i) {
X[i + N / 2] = tmp[i];
}

fft(X, N / 2);
fft(X + N / 2, N / 2);

for (size_t i = 0; i < N / 2; ++i) {
X[i + N/2] = X[i] - cexp(-2.0 * I * M_PI * i / N) * X[i + N / 2];
X[i] -= (X[i + N / 2] - X[i]);
}
}
}

void ifft(double complex *x, size_t n) {
for (size_t i = 0; i < n; ++i) {
x[i] = conj(x[i]);
}

fft(x, n);

for (size_t i = 0; i < n; ++i) {
x[i] = conj(x[i]) / n;
}
}

// This section is a part of the algorithm
#include <stdio.h>

void conv(double complex *signal1, double complex *signal2, double complex* out,
size_t n1, size_t n2) {
size_t n1, size_t n2) {
double complex sum = 0;

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

void conv_fft(double complex *signal1, double complex *signal2,
double complex* out, size_t n) {
double complex* out, size_t n) {
fft(signal1, n);
fft(signal2, n);

Expand Down
41 changes: 41 additions & 0 deletions chapters/convolutions/code/c/fft.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef FFT_H
#define FFT_H

#include <complex.h>
#include <math.h>

void fft(double complex *X, size_t N) {
if (N >= 2) {
double complex tmp [N / 2];
for (size_t i = 0; i < N / 2; ++i) {
tmp[i] = X[2 * i + 1];
X[i] = X[2 * i];
}

for (size_t i = 0; i < N / 2; ++i) {
X[i + N / 2] = tmp[i];
}

fft(X, N / 2);
fft(X + N / 2, N / 2);

for (size_t i = 0; i < N / 2; ++i) {
X[i + N/2] = X[i] - cexp(-2.0 * I * M_PI * i / N) * X[i + N / 2];
X[i] -= (X[i + N / 2] - X[i]);
}
}
}

void ifft(double complex *x, size_t n) {
for (size_t i = 0; i < n; ++i) {
x[i] = conj(x[i]);
}

fft(x, n);

for (size_t i = 0; i < n; ++i) {
x[i] = conj(x[i]) / n;
}
}

#endif //FFT_H
4 changes: 2 additions & 2 deletions chapters/convolutions/convolutions.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ In code, this looks something like:
{% sample lang="hs" %}
[import:1-5, lang:"haskell"](code/haskell/convolution.hs)
{% sample lang="c"%}
[import:44-57, lang:"c_cpp"](code/c/convolutions.c)
[import:5-18, lang:"c_cpp"](code/c/convolutions.c)
{% sample lang="cpp"%}
[import:68-88, lang:"c_cpp"](code/c++/convolutions.cpp)
{% endmethod %}
Expand Down Expand Up @@ -90,7 +90,7 @@ The FFT-based convolution in Haskell is complicated, so here is some simple juli
[import:19-22, lang:"julia"](code/julia/conv.jl)
Where the `.*` operator is an element-wise multiplication.
{% sample lang="c"%}
[import:59-69, lang:"c_cpp"](code/c/convolutions.c)
[import:20-30, lang:"c_cpp"](code/c/convolutions.c)
{% sample lang="cpp"%}
[import:90-105, lang:"c_cpp"](code/c++/convolutions.cpp)
{% endmethod %}
Expand Down
169 changes: 86 additions & 83 deletions chapters/decision_problems/stable_marriage/code/c/stable_marriage.c
Original file line number Diff line number Diff line change
@@ -1,118 +1,121 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>

struct person {
int id;
struct person *partner;
size_t *prefers;
size_t index;
};

void shuffle(size_t *array, size_t size) {
for (size_t i = size - 1; i > 0; --i) {
size_t j = rand() % (i + 1);
size_t tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}

void create_group(struct person *group, size_t size, bool are_men) {
for (size_t i = 0; i < size; ++i) {
group[i].id = i;
group[i].partner = NULL;
group[i].prefers = (size_t*)malloc(sizeof(size_t) * size);
group[i].index = 0;

typedef struct person {
size_t id;
size_t prtnr;
size_t *prefs;
size_t pref_ind;
} person;

void shuffle(size_t *x, size_t n) {
if (n > 1) {
for (size_t i = 0; i < n - 1; ++i) {
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
size_t t = x[j];
x[j] = x[i];
x[i] = t;
for (size_t j = 0; j < size; ++j) {
group[i].prefers[j] = j;
}

shuffle(group[i].prefers, size);
}
}

bool prefers(size_t *prefs, size_t prtnr_id, size_t prop_id, size_t pref_size) {
for (size_t i = 0; i < pref_size; ++i) {
if (prefs[i] == prtnr_id) {
return false;
} else if(prefs[i] == prop_id) {
bool prefers_partner(size_t *prefers, size_t partner, size_t id, size_t size) {
for (size_t i = 0; i < size; ++i) {
if (prefers[i] == partner) {
return true;
} else if(prefers[i] == id) {
return false;
}
}
}

void create_ppl(person *grp, size_t grp_size) {
for (size_t i = 0; i < grp_size; ++i) {
person prn;
prn.id = i;
prn.prtnr = grp_size + 1;
prn.pref_ind = 0;
prn.prefs = (size_t *) malloc(sizeof(size_t) * grp_size);

for (size_t j = 0; j < grp_size; ++j) {
prn.prefs[j] = j;
}
void stable_marriage(struct person *men, struct person *women, size_t size) {
struct person *bachelors[size];
size_t bachelors_size = size;

shuffle(prn.prefs, grp_size);
grp[i] = prn;
for (size_t i = 0; i < size; ++i) {
bachelors[i] = &men[i];
}
}

void stable_matching(person *men, person *women, size_t grp_size) {
bool cont = true;
while (cont) {
for (size_t i = 0; i < grp_size; ++i) {
if (men[i].prtnr == (grp_size + 1)) {
size_t wmn_id = men[i].prefs[men[i].pref_ind];

if (women[wmn_id].prtnr == (grp_size + 1)) {
men[i].prtnr = wmn_id;
women[wmn_id].prtnr = i;
} else if(prefers(women[wmn_id].prefs, women[wmn_id].prtnr, i,
grp_size)) {
men[women[wmn_id].prtnr].prtnr = grp_size + 1;
women[wmn_id].prtnr = i;
men[i].prtnr = wmn_id;
}

men[i].pref_ind++;
}
}

cont = false;
for (size_t i = 0; i < grp_size; ++i) {
if (men[i].prtnr == (grp_size + 1)) {
cont = true;
break;
}
while (bachelors_size > 0) {
struct person *man = bachelors[bachelors_size - 1];
struct person *woman = &women[man->prefers[man->index]];

if (!woman->partner) {
woman->partner = man;
man->partner = woman;
bachelors[--bachelors_size] = NULL;
} else if (!prefers_partner(woman->prefers, woman->partner->id, man->id,
size)) {

woman->partner->index++;
bachelors[bachelors_size - 1] = woman->partner;
woman->partner = man;
man->partner = woman;
} else {
man->index++;
}
}
}

void kill(person *grp, size_t grp_size) {
for (size_t i = 0; i < grp_size; ++i) {
free(grp[i].prefs);
void free_group(struct person *group, size_t size) {
for (size_t i = 0; i < size; ++i) {
free(group[i].prefers);
}
}

int main() {
int grp_size = 5;
person men[grp_size], women[grp_size];
srand(time(NULL));

create_ppl(men, grp_size);
create_ppl(women, grp_size);
struct person men[5], women[5];

stable_matching(men, women, grp_size);
create_group(men, 5, true);
create_group(women, 5, false);

for (size_t i = 0; i < grp_size; ++i) {
printf("preferences of man %zu \n", i);
for (size_t j = 0; j < grp_size; ++j) {
printf("%zu \n", men[i].prefs[j]);
for (size_t i = 0; i < 5; ++i) {
printf("preferences of man %zu: ", i);
for (size_t j = 0; j < 5; ++j) {
printf("%zu ", men[i].prefers[j]);
}

printf("\n");
}

for (size_t i = 0; i < grp_size; ++i) {
printf("preferences of woman %zu \n", i);
for (size_t j = 0; j < grp_size; ++j) {
printf("%zu \n", women[i].prefs[j]);
printf("\n");

for (size_t i = 0; i < 5; ++i) {
printf("preferences of woman %zu: ", i);
for (size_t j = 0; j < 5; ++j) {
printf("%zu ", women[i].prefers[j]);
}
}

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

kill(men, grp_size);
kill(women, grp_size);
stable_marriage(men, women, 5);

printf("\n");

for (size_t i = 0; i < 5; ++i) {
printf("the partner of man %zu is woman %d\n", i, men[i].partner->id);
}

return 0;
free_group(men, 5);
free_group(women, 5);
}