From 9b4942e0048d6d98aef43e368a6a07e43ac614d2 Mon Sep 17 00:00:00 2001 From: ametama Date: Mon, 19 Jan 2026 20:25:56 +0100 Subject: [PATCH] refac: header consolidation + memory fix in de --- include/cgo.h | 3 +++ include/{swarm.h => pso.h} | 13 ++++++------- include/rand.h | 5 +++++ src/de.c | 27 +++++++++++++-------------- src/main.c | 30 +++++++++++++++++++++++++++++- src/{swarm.c => pso.c} | 12 ++++++------ 6 files changed, 62 insertions(+), 28 deletions(-) create mode 100644 include/cgo.h rename include/{swarm.h => pso.h} (63%) rename src/{swarm.c => pso.c} (88%) diff --git a/include/cgo.h b/include/cgo.h new file mode 100644 index 0000000..f81d509 --- /dev/null +++ b/include/cgo.h @@ -0,0 +1,3 @@ +#include "de.h" +#include "pso.h" +#include "vector.h" diff --git a/include/swarm.h b/include/pso.h similarity index 63% rename from include/swarm.h rename to include/pso.h index cfeb33f..b888dbe 100644 --- a/include/swarm.h +++ b/include/pso.h @@ -16,7 +16,7 @@ typedef struct { double w; // inertia double c; // cognitive factor double s; // social factor -} swarm_parameters; +} pso_parameters; typedef struct { particle *particles; @@ -29,9 +29,8 @@ struct particle { double *velocity; }; -void swarm_alloc(swarm_parameters *par, swarm *sw); -void swarm_free(swarm_parameters *par, swarm *sw); -void swarm_populate(swarm_parameters *par, swarm *sw, const range *rrange); -void swarm_velocity_update(swarm_parameters *par, swarm *sw); - -void swarm_optimize(swarm_parameters *par, particle_state *res); +void swarm_alloc(pso_parameters *par, swarm *sw); +void swarm_free(pso_parameters *par, swarm *sw); +void swarm_populate(pso_parameters *par, swarm *sw, const range *rrange); +void swarm_velocity_update(pso_parameters *par, swarm *sw); +void pso_optimize(pso_parameters *par, particle_state *res); diff --git a/include/rand.h b/include/rand.h index 7c0373d..172d694 100644 --- a/include/rand.h +++ b/include/rand.h @@ -1,3 +1,6 @@ +#ifndef RAND_H +#define RAND_H + typedef struct { double min; double max; @@ -6,3 +9,5 @@ typedef struct { double rands(); double randrange(double min, double max); void vec_pick(const int dim, const range *rrange, double *v); + +#endif diff --git a/src/de.c b/src/de.c index 441312b..0e9f72c 100644 --- a/src/de.c +++ b/src/de.c @@ -4,26 +4,25 @@ void de_optimize(de_parameters *par, double *res) { int l = par->particlec * par->dim; - double *mem = malloc(sizeof(double) * l * 2); + double *mem = malloc(sizeof(double) * (l + par->dim)); int conv = 0; double *xs = mem; - double *ys = mem + l; - for (double *x = xs; x < ys; x += par->dim) + double *y = mem + l; + for (double *x = xs; x < y; x += par->dim) vec_pick(par->dim, par->rrange, x); while (conv < 1000) { - for (double *x = xs; x < ys; x += par->dim) { - double *y = x + l; + for (double *x = xs; x < y; x += par->dim) { double *picks[4] = { x }; // agents { x, a, b, c } - for (int i = 1; i < 4; i++) { - double *pick = xs + (rand() % (par->particlec - i)); - picks[i] = pick; - for (int k = 0; k < i; k++) - if (pick >= picks[k]) picks[i]++; + for (int a = 1; a < 4; a++) { + double *pick = xs + (rand() % (par->particlec - a)); + picks[a] = pick; + for (int ap = 0; ap < a; ap++) + if (pick >= picks[ap]) picks[a]++; } int r = rand() % par->dim; - for (int i = 0; i < par->dim; i++) { - if (i == r || rands() < par->cr) y[i] = picks[1][i] + par->dw * (picks[2][i] - picks[3][i]); - else y[i] = x[i]; + for (int d = 0; d < par->dim; d++) { + if (d == r || rands() < par->cr) y[d] = picks[1][d] + par->dw * (picks[2][d] - picks[3][d]); + else y[d] = x[d]; } if (par->f(y) < par->f(x)) { vec_copy(par->dim, y, x); @@ -34,7 +33,7 @@ void de_optimize(de_parameters *par, double *res) { } double *best = xs; double bestf = par->f(best); - for (double *x = xs; x < ys; x += par->dim) { + for (double *x = xs; x < y; x += par->dim) { double cur = par->f(x); if (cur < bestf) { best = x; diff --git a/src/main.c b/src/main.c index b75439c..f900b93 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,7 @@ #include #include +#include +#include "cgo.h" enum algorithm { de, @@ -39,11 +41,37 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { static struct argp argp = { options, parse_opt, args_doc, doc }; +double b0(double *x) { + return -x[0]; +} + +double b1(double *x) { + return -x[1]; +} + +double b2(double *x) { + return x[0] - 10; +} + +double b3(double *x) { + return x[1] - 15; +} + +double f(double *x) { + return exp(b0(x)) + exp(b1(x)) + exp(b2(x)) + exp(b3(x)) + x[0] - x[1]; +} + int main(int argc, char *argv[]) { struct arguments args; args.algorithm = de; args.outfile = "out.log"; argp_parse(&argp, argc, argv, 0, 0, &args); - + range sample[2] = { (range) { -100.0, 100.0 }, { -100.0, 100.0 } }; + de_parameters par = {2, 1000, sample, f}; + double *res = vec_alloc(2); + de_optimize(&par, res); + printf("Converged at x="); + vec_print(2, res); + printf(" with fitness f(x)=%f\n", f(res)); return 0; } diff --git a/src/swarm.c b/src/pso.c similarity index 88% rename from src/swarm.c rename to src/pso.c index 028f51b..e7efa80 100644 --- a/src/swarm.c +++ b/src/pso.c @@ -1,10 +1,10 @@ #include #include #include -#include "swarm.h" +#include "pso.h" #include "vector.h" -void swarm_alloc(swarm_parameters *par, swarm *sw) { +void swarm_alloc(pso_parameters *par, swarm *sw) { sw->particles = malloc(sizeof(particle) * par->particlec); #pragma omp parallel for for (int p = 0; p < par->particlec; p++) { @@ -14,7 +14,7 @@ void swarm_alloc(swarm_parameters *par, swarm *sw) { } } -void swarm_free(swarm_parameters *par, swarm *sw) { +void swarm_free(pso_parameters *par, swarm *sw) { #pragma omp parallel for for (int p = 0; p < par->particlec; p++) { free(sw->particles[p].current.x); @@ -24,7 +24,7 @@ void swarm_free(swarm_parameters *par, swarm *sw) { free(sw->particles); } -void swarm_populate(swarm_parameters *par, swarm *sw, const range *rrange) { +void swarm_populate(pso_parameters *par, swarm *sw, const range *rrange) { sw->global_best = &sw->particles[0]; #pragma omp parallel for for (int p = 0; p < par->particlec; p++) { @@ -43,7 +43,7 @@ void swarm_populate(swarm_parameters *par, swarm *sw, const range *rrange) { } } -void swarm_velocity_update(swarm_parameters *par, swarm *sw) { +void swarm_velocity_update(pso_parameters *par, swarm *sw) { #pragma omp parallel for for (int p = 0; p < par->particlec; p++) { particle *pt = &sw->particles[p]; @@ -67,7 +67,7 @@ void swarm_velocity_update(swarm_parameters *par, swarm *sw) { } } -void swarm_optimize(swarm_parameters *par, particle_state *res) { +void pso_optimize(pso_parameters *par, particle_state *res) { swarm sw; swarm_alloc(par, &sw); swarm_populate(par, &sw, par->rrange); -- 2.34.1