diff --git a/chapters/convolutions/code/c/convolutions.c b/chapters/convolutions/code/c/convolutions.c index ca2d747cb..386285a1d 100644 --- a/chapters/convolutions/code/c/convolutions.c +++ b/chapters/convolutions/code/c/convolutions.c @@ -1,48 +1,9 @@ -#include -#include - -// This section is not a part of the algorithm - -#include +#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 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) { @@ -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); diff --git a/chapters/convolutions/code/c/fft.h b/chapters/convolutions/code/c/fft.h new file mode 100644 index 000000000..de789f197 --- /dev/null +++ b/chapters/convolutions/code/c/fft.h @@ -0,0 +1,41 @@ +#ifndef FFT_H +#define FFT_H + +#include +#include + +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 diff --git a/chapters/convolutions/convolutions.md b/chapters/convolutions/convolutions.md index 0472d79dd..cfae168e4 100644 --- a/chapters/convolutions/convolutions.md +++ b/chapters/convolutions/convolutions.md @@ -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 %} @@ -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 %} diff --git a/chapters/decision_problems/stable_marriage/code/c/stable_marriage.c b/chapters/decision_problems/stable_marriage/code/c/stable_marriage.c index 677636362..546a0d5d1 100644 --- a/chapters/decision_problems/stable_marriage/code/c/stable_marriage.c +++ b/chapters/decision_problems/stable_marriage/code/c/stable_marriage.c @@ -1,118 +1,121 @@ +#include #include #include -#include +#include +#include + +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); }