commit 2b6d059fb5072642f2df6a8c5fb3cca2de2c42f4 Author: Dukantic Date: Mon Oct 12 19:45:30 2026 +0200 Init project after finished it and start of the report diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c139e44 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.jpeg filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40eba28 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +**/*.pdf +.DS_Store +.idea diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c5308d4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 4.3) +project(SimulationRabbit C) + +set(CMAKE_C_STANDARD 11) + +add_executable(SimulationRabbit main.c + rabbit_hole.c + rabbit_hole.h + mt19937ar.c + mt19937ar.h) diff --git a/graph.py b/graph.py new file mode 100644 index 0000000..0e44916 --- /dev/null +++ b/graph.py @@ -0,0 +1,20 @@ +import numpy as np +import matplotlib.pyplot as plt + +data = np.loadtxt("rabbits.csv", delimiter=",", skiprows=1, usecols=(0, 1)) +month, total = data[:, 0], data[:, 1] + +fig, ax = plt.subplots(figsize=(9, 5)) +ax.plot(month, total, lw=2, color="tab:blue") + +ax.set_yscale("log") +ax.set_xlim(0, month.max()) +ax.set_ylim(10, total.max() * 3) +ax.set_xticks(np.arange(0, month.max() + 1, 24)) +ax.grid(True, which="both", axis="y", alpha=0.3) +ax.set_xlabel("Month") +ax.set_ylabel("Total rabbits (log)") +ax.set_title("Simulation Rabbit — population totale") + +fig.tight_layout() +plt.show() \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..01c5828 --- /dev/null +++ b/main.c @@ -0,0 +1,22 @@ +#include +#include "rabbit_hole.h" +#include "mt19937ar.h" + +int main(void) { + init_genrand(42); + printf("===========Rabbit Hole Simulation =============\n"); + rabbit_hole_t rabbits; + init_rabbits(&rabbits); + rabbits.male_mature[0] = 10; + rabbits.female_mature[0] = 10; + __uint128_t month = 0; + print_rabbits(&rabbits,&month); + csv_header(); + for (int j = 0; j < 12*80 ; j++) { + if (!process_month(&rabbits,&month)) + break; + print_rabbits(&rabbits,&month); + } + + return 0; +} diff --git a/mt19937ar.c b/mt19937ar.c new file mode 100755 index 0000000..951cf04 --- /dev/null +++ b/mt19937ar.c @@ -0,0 +1,216 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include +#include "mt19937ar.h" +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti = N + 1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) { + mt[0] = s & 0xffffffffUL; + for (mti = 1; mti < N; mti++) { + mt[mti] = (1812433253UL * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) { + int i, j, k; + init_genrand(19650218UL); + i = 1; + j = 0; + k = (N > key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + j++; + if (i >= N) { + mt[0] = mt[N - 1]; + i = 1; + } + if (j >= key_length) + j = 0; + } + for (k = N - 1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941UL)) - + i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i >= N) { + mt[0] = mt[N - 1]; + i = 1; + } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) { + unsigned long y; + static unsigned long mag01[2] = {0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N + 1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk = 0; kk < N - M; kk++) { + y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); + mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + for (; kk < N - 1; kk++) { + y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); + mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); + mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) { + return (long)(genrand_int32() >> 1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) { + return genrand_int32() * (1.0 / 4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) { + return genrand_int32() * (1.0 / 4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) { + return (((double)genrand_int32()) + 0.5) * (1.0 / 4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) { + unsigned long a = genrand_int32() >> 5, b = genrand_int32() >> 6; + return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +double uniform(double a, double b) { + return (genrand_real2() * (b - a)) + a; +} + +char distribution_abc() { + double dice = genrand_real2(); + if (dice <= 0.35) + return 'C'; + else if (dice <= 0.5) + return 'B'; + return 'A'; +} + +int distribution_array(int* array, int n) { + int i, total = 0; + double draw = genrand_real2(); + for (i = 0; i < n; i++) { + total += array[i]; + } + + int current_count = 0; + for (i = 0; i < n; i++) { + current_count += array[i]; + if (draw <= (current_count / (double)total)) + return i; + } + return n - 1; +} + +double negExp(double m) { + return -m * log(1 - genrand_real2()); +} + +void gauss(double* x_1_2) { + double rn1 = genrand_real2(), rn2 = genrand_real2(); + double p = pow(-2 * log(rn2), 0.5); + x_1_2[0] = cos(2 * 3.1415 * rn1) * p; + x_1_2[1] = sin(2 * 3.1415 * rn1) * p; +} + + diff --git a/mt19937ar.h b/mt19937ar.h new file mode 100644 index 0000000..9d08b53 --- /dev/null +++ b/mt19937ar.h @@ -0,0 +1,15 @@ +// +// Created by dukantic on 29/09/2026. +// + +#ifndef SIMULATIONRABBIT_MT19937AR_H +#define SIMULATIONRABBIT_MT19937AR_H + +void init_genrand(unsigned long s); +double genrand_real1(void); +double genrand_real2(void); +double uniform(double a, double b); +int distribution_array(int *array, int n); +void gauss(double* x_1_2) ; + +#endif //SIMULATIONRABBIT_MT19937AR_H diff --git a/rabbit_hole.c b/rabbit_hole.c new file mode 100644 index 0000000..e261a10 --- /dev/null +++ b/rabbit_hole.c @@ -0,0 +1,387 @@ +// +// Created by dukantic on 29/09/2026. +// +#ifndef RABBIT_HOLE_H +#define RABBIT_HOLE_H +#include "rabbit_hole.h" + +#include + +#include + +#include "mt19937ar.h" +__uint128_t i,j; +double x_gauss[2]; + +void init_rabbits(rabbit_hole_t *rabbits) { + rabbits->female_litter=0; + for (i = 0; i < N_MATURE; i++) { + rabbits->male_mature[i] =0; + rabbits->female_mature[i] =0; + } + + for (i = 0; i < N_KITTEN; i++) { + rabbits->kitten_male[i] =0; + rabbits->kitten_female[i] =0; + } +} + +double sk_sigma_m, sk_mu_m, sk_sigma_f, sk_mu_f; +double sk_draw; +__uint128_t sk_temp_male, sk_temp_female; +void shift_kitten(rabbit_hole_t *rabbits, __uint128_t *new_male, __uint128_t *new_female) { + (*new_male) = rabbits->kitten_male[N_KITTEN-1]; + (*new_female) = rabbits->kitten_female[N_KITTEN-1]; + for (i = N_KITTEN - 3; i < N_KITTEN-1; i++) { + sk_temp_male = 0; + sk_temp_female = 0; + if (rabbits->kitten_male[i]<100 || rabbits->kitten_female[i]<100) { + for ( j = 0; j < rabbits->kitten_male[i]; j++) { + sk_draw = genrand_real1(); + if (sk_draw <= 0.66) + sk_temp_male ++; + } + for (j = 0; j < rabbits->kitten_female[i]; j++) { + sk_draw = genrand_real1(); + if (sk_draw <= 0.66) + sk_temp_female ++; + } + rabbits->kitten_male[i]-= sk_temp_male; + rabbits->kitten_female[i]-= sk_temp_female; + (*new_male) += sk_temp_male; + (*new_female) += sk_temp_female; + } + else + { + gauss(x_gauss); + sk_mu_m = (double)rabbits->kitten_male[i] * 0.66; + sk_sigma_m = sqrt(sk_mu_m * 0.33); + sk_mu_f = (double)rabbits->kitten_female[i] * 0.66; + sk_sigma_f = sqrt(sk_mu_f * 0.33); + x_gauss[0] = CLAMP_BTW(x_gauss[0] * sk_sigma_m + sk_mu_m, 0.0, rabbits->kitten_male[i]); + x_gauss[1] = CLAMP_BTW( x_gauss[1] * sk_sigma_f + sk_mu_f, 0.0, rabbits->kitten_female[i]); + (*new_male) += (__uint128_t)roundl(x_gauss[0]); + (*new_female) += (__uint128_t)roundl(x_gauss[1]); + rabbits->kitten_male[i] -= (__uint128_t)roundl(x_gauss[0]); + rabbits->kitten_female[i] -= (__uint128_t)roundl(x_gauss[1]); + } + + } + for (i = N_KITTEN-1; i >=1; i--) { + rabbits->kitten_male[i] = rabbits->kitten_male[i-1]; + rabbits->kitten_female[i] = rabbits->kitten_female[i-1]; + } + rabbits->kitten_male[0] = 0; + rabbits->kitten_female[0] = 0; +} + +__uint128_t *males; +__uint128_t *females; +double draw; +void shift_mature(rabbit_hole_t* rabbits) { + males = rabbits->male_mature; + females = rabbits->female_mature; + + for (i = N_MATURE-1; i >=1; i--) { + males[i] = males[i-1]; + females[i] = females[i-1]; + } + males[0] = 0; + females[0] = 0; +} + +double dp_threshold_death, dp_draw_death; +double sigma_m,sigma_f, mu_m, mu_f; +__uint128_t temp_male, temp_female; +void death_process(rabbit_hole_t *rabbits) { + for (i =0; i < N_MATURE; i++) { + dp_threshold_death = 1 - (0.4 + ((i >= 9)? (double)(i-9) * 0.1: 0)) / 12; + if (rabbits->male_mature[i] < 100 || rabbits->female_mature[i] < 100) { + temp_male = 0; + temp_female = 0; + for (j = 0; j < rabbits->male_mature[i]; j++) { + dp_draw_death = genrand_real1(); + if (dp_draw_death <= dp_threshold_death) + temp_male ++; + } + + for (j = 0; j < rabbits->female_mature[i]; j++) { + dp_draw_death = genrand_real1(); + if (dp_draw_death <= dp_threshold_death) + temp_female ++; + } + rabbits->male_mature[i] = temp_male; + rabbits->female_mature[i] = temp_female; + }else { + mu_f = (double)rabbits->female_mature[i] * dp_threshold_death; + sigma_f = sqrt(mu_f * (1.0-dp_threshold_death)); + mu_m = (double)rabbits->male_mature[i] * dp_threshold_death; + sigma_m = sqrt(mu_m * (1.0-dp_threshold_death)); + + gauss(x_gauss); + x_gauss[0] = CLAMP_BTW(x_gauss[0] * sigma_f + mu_f, 0.0, (double)rabbits->female_mature[i]); + x_gauss[1] = CLAMP_BTW(x_gauss[1] * sigma_m + mu_m, 0.0, (double)rabbits->male_mature[i]); + rabbits->female_mature[i] = (__uint128_t)roundl(x_gauss[0]); + rabbits->male_mature[i] = (__uint128_t)roundl(x_gauss[1]); + } + } + + for (i = 0; i < N_KITTEN; i++) { + if (rabbits->kitten_male[i] < 100 || rabbits->kitten_female[i] < 100) { + temp_male = 0; + temp_female = 0; + for (j = 0; j < rabbits->kitten_male[i]; j++) { + dp_draw_death = genrand_real1(); + if (dp_draw_death > 0.05) //0.35/7 + temp_male ++; + } + for (j = 0; j < rabbits->kitten_female[i]; j++) { + dp_draw_death = genrand_real1(); + if (dp_draw_death > 0.05) //0.35/7 + temp_female ++; + } + rabbits->kitten_male[i] = temp_male; + rabbits->kitten_female[i] = temp_female; + }else { + mu_f = (double)rabbits->kitten_female[i] * 0.95; + sigma_f = sqrt(mu_f * 0.05); + mu_m = (double)rabbits->kitten_male[i] * 0.95; + sigma_m = sqrt(mu_m * 0.05); + + gauss(x_gauss); + x_gauss[0] = x_gauss[0] * sigma_f + mu_f; + x_gauss[1] = x_gauss[1] * sigma_m + mu_m; + rabbits->kitten_female[i] = (__uint128_t)roundl(x_gauss[0]); + rabbits->kitten_male[i] = (__uint128_t)roundl(x_gauss[1]); + } + } +} + +__uint128_t nb_females; +int taille1; +__uint128_t new_litter; +double draw_litter; +double ul_mu_k,ul_sigma_k, ul_mu_sex, ul_sigma_sex; +double ul_mu_litter, ul_sigma_litter; +void update_litter(rabbit_hole_t *rabbits, __uint128_t *new_kitten_male, __uint128_t *new_kitten_female) { + (*new_kitten_female) = 0; + (*new_kitten_male) = 0; + // sigma par femelle carre = ((b-a+1)caree- 1)/12 = 4 + // sigma par femelle = 2 + //sigma total = sqrt(sigma par femelle carre * N) + //mu = ((9+3)/2 ) * N = 6 * N + if (rabbits->female_litter < 100) { + for (i = 0; i < rabbits->female_litter; i++) { + taille1 = 3 + (int)(4.0 * genrand_real2()); //TODO + taille1 = 3 + (int)(4.0 * genrand_real2()); //TODO + for (int k = 0; k < taille1; k++) { + if (genrand_real1() > 0.5) (*new_kitten_male)++; + else (*new_kitten_female)++; + } + + } + }else { + ul_mu_k = 6.0*(double)rabbits->female_litter; + ul_sigma_k = sqrt(4.0 * (double)rabbits->female_litter); + gauss(x_gauss); + x_gauss[0] = CLAMP_BTW(x_gauss[0] * ul_sigma_k+ ul_mu_k, 0.0 , rabbits->female_litter * 9.0); + + ul_mu_sex = x_gauss[0] * 0.5; + ul_sigma_sex = sqrt(ul_mu_sex * 0.5); + x_gauss[1] = CLAMP_BTW(x_gauss[1] * ul_sigma_sex + ul_mu_sex , 0.0, rabbits->female_litter * 9.0); + + (*new_kitten_female) = (__uint128_t)roundl(x_gauss[1]) ; + (*new_kitten_male) = (__uint128_t)roundl(x_gauss[0] - x_gauss[1]); + } + + nb_females = 0; + for (i = 0; i < N_MATURE; i++) { + nb_females += rabbits->female_mature[i]; + } + + if (nb_females < 100) { + new_litter = 0; + for (i = 0; i < nb_females; i++) { + draw_litter = genrand_real1(); + if (draw_litter > 0.5) + new_litter++; + } + rabbits->female_litter = new_litter; + }else { + ul_mu_litter = (double)nb_females * 0.5; + ul_sigma_litter = sqrt(ul_mu_litter * 0.5); + gauss(x_gauss); + x_gauss[0] = CLAMP_BTW(x_gauss[0]* ul_sigma_litter + ul_mu_litter ,0.0,nb_females); + rabbits->female_litter = (__uint128_t)roundl(x_gauss[0]); + + } +} + + +char total_rabbits(rabbit_hole_t *rabbits, __uint128_t *total) { + *total = 0; + __uint128_t total_temp; + + for (i = 0; i < N_MATURE; i++) { + total_temp = *total; + *total += rabbits->male_mature[i]; + *total += rabbits->female_mature[i]; + if (*total < total_temp) //overflow + { + return 0; + } + } + for (i = 0; i < N_KITTEN; i++) { + total_temp = *total; + *total += rabbits->kitten_male[i]; + *total += rabbits->kitten_female[i]; + if (*total < total_temp) //overflow + { + return 0; + } + } + return 1; +} + +static void u128_to_str(__uint128_t v, char *buf) +{ + char tmp[45]; + int i = 0, j = 0; + + if (v == 0) { + buf[0] = '0'; + buf[1] = '\0'; + return; + } + while (v > 0) { + tmp[i++] = '0' + (char)(v % 10); + v /= 10; + } + while (i > 0) + buf[j++] = tmp[--i]; + buf[j] = '\0'; +} + +static void print_u128(__uint128_t v) +{ + char buf[45]; + u128_to_str(v, buf); + printf("%s", buf); +} + +static void print_row_u128(const char *label, const __uint128_t *arr, size_t n) +{ + fputs(label, stdout); + fputs("| ", stdout); + for (size_t i = 0; i < n; i++) { + print_u128(arr[i]); + fputs(" | ", stdout); + } + putchar('\n'); +} + + +char print_rabbits(rabbit_hole_t *rabbits, __uint128_t *month) +{ + printf("During time : "); + print_u128(*month / 12); + printf(" years, "); + print_u128(*month % 12); + printf(" months\n"); + + print_row_u128("Male : ", rabbits->male_mature, N_MATURE); + print_row_u128("Female : ", rabbits->female_mature, N_MATURE); + print_row_u128("Male kitten : ", rabbits->kitten_male, N_KITTEN); + print_row_u128("Female kitten : ", rabbits->kitten_female, N_KITTEN); + + printf("\nLitter : | "); + print_u128(rabbits->female_litter); + printf("\n=> "); + __uint128_t total; + if ( ! total_rabbits(rabbits,&total)) { + puts("======================OVERFLOW==================="); + return 0; + } + + print_u128(total); + printf("\n"); + + puts("########################################"); + return 1; +} + +void csv_header() { + fprintf(stderr, "Month, Total Rabbit, Litters,"); + for ( i = 0; i < N_MATURE; i++) { + fprintf(stderr,"Male (age %d),",i+1); + } + for (i = 0; i < N_MATURE; i++) { + fprintf(stderr,"Female (age %d),",i+1); + } + for (i = 0; i < N_KITTEN; i++) { + fprintf(stderr,"Kitten Male (age %d),",i+1); + } + for (i = 0; i < N_KITTEN; i++) { + fprintf(stderr,"Kitten Female (age %d),",i+1); + } + fprintf(stderr, "\n"); +} + +char csv_rabbits(rabbit_hole_t *rabbits, const __uint128_t *month) { + __uint128_t total; + if (!total_rabbits(rabbits,&total)) + return 0; + char number_string[512]; + u128_to_str(*month, number_string); + fprintf(stderr, "%s,", number_string); + u128_to_str(total,number_string); + fprintf(stderr, "%s,", number_string); + u128_to_str(rabbits->female_litter,number_string); + fprintf(stderr, "%s,", number_string); + for ( i = 0; i < N_MATURE; i++) { + u128_to_str(rabbits->male_mature[i],number_string); + fprintf(stderr,"%s,", number_string); + } + for (i = 0; i < N_MATURE; i++) { + u128_to_str(rabbits->female_mature[i],number_string); + fprintf(stderr,"%s,", number_string); + } + + for (i = 0; i < N_KITTEN; i++) { + u128_to_str(rabbits->kitten_male[i],number_string); + fprintf(stderr,"%s,", number_string); + } + for (i = 0; i < N_KITTEN; i++) { + u128_to_str(rabbits->kitten_female[i],number_string); + fprintf(stderr,"%s,", number_string); + } + fprintf(stderr, "\n"); + return 1; +} + +__uint128_t new_male; +__uint128_t new_female; +__uint128_t new_kitten_male; +__uint128_t new_kitten_female; +char process_month(rabbit_hole_t *rabbits,__uint128_t *month) { + shift_kitten(rabbits, &new_male, &new_female); + if (*month % 12 == 0) { + shift_mature(rabbits); + } + rabbits->male_mature[0] += new_male; + rabbits->female_mature[0] += new_female; + death_process(rabbits); + update_litter(rabbits, &new_kitten_male, &new_kitten_female); + rabbits->kitten_male[0] += new_kitten_male; + rabbits->kitten_female[0] += new_kitten_female; + (*month)++; + if (!csv_rabbits(rabbits,month)) + return 0; + return 1; +} + + + + +#endif + diff --git a/rabbit_hole.h b/rabbit_hole.h new file mode 100644 index 0000000..71a25b8 --- /dev/null +++ b/rabbit_hole.h @@ -0,0 +1,31 @@ +// +// Created by dukantic on 29/09/2026. +// + +#ifndef SIMULATIONRABBIT_RABBIT_HOLE_H +#define SIMULATIONRABBIT_RABBIT_HOLE_H +#include + +#define N_MATURE (16) +#define N_KITTEN (8) + +#define CLAMP(x,y) (x >= y? y :x) +#define CLAMP_BTW(a, lo, hi) ((a) < (lo) ? (lo) : ((a) > (hi) ? (hi) : (a))) + + +typedef struct rabbit_hole_s { + __uint128_t male_mature[N_MATURE]; + __uint128_t female_mature[N_MATURE]; + __uint128_t female_litter; + __uint128_t kitten_male[N_KITTEN]; + __uint128_t kitten_female[N_KITTEN]; +} rabbit_hole_t; + + + +void init_rabbits(rabbit_hole_t *rabbits); +char process_month(rabbit_hole_t *rabbits,__uint128_t *month); +void csv_header(); +char print_rabbits(rabbit_hole_t *rabbits, __uint128_t *month); + +#endif //SIMULATIONRABBIT_RABBIT_HOLE_H diff --git a/repport/SimulationLapin.tex b/repport/SimulationLapin.tex new file mode 100644 index 0000000..36d9297 --- /dev/null +++ b/repport/SimulationLapin.tex @@ -0,0 +1,70 @@ +\documentclass[11pt, a4paper]{article} + +% Préambule : packages utiles +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[french]{babel} +\usepackage{graphicx} +\usepackage{amsmath} +\usepackage{hyperref} +\graphicspath{ {./images/} } + +\title{Simulation de population de lapin \\ (Rabbit's hole)} +\author{Aubin DORIVAL F2 Promo 28} +\date{\today} + +\begin{document} +\maketitle + +\begin{center} + \url{https://git.dukantic.fr/dukantic/Rabbit-s-Hole} + \includegraphics[width=0.7\textwidth]{draw_rabbit.jpg} +\end{center} + +\section{Introduction} +Le projet `Rabbit Hole` est une simulation de population de lapin. Elle +essaye de simuler la croissance de la population de lapin en essayant de +suivre certaine règles et en faisant abstraction d'autre choses. Dans +tout le projet j'ai globalement prit les conditions et les probabilités +qui sont dans le sujet de base. + + +\section{Règles} +Tout d'abord il faut définir les règles à suivre. + +\begin{itemize} + \item Taux de gestation à $50\%$ par mois. + \item $3$ à $6$ bébés par gestation de manière uniforme. + \item Les bébés deviennent adulte entre le $5\up{eme}$ et $8\up{eme}$ mois + \item Les adultes meurent avec un taux de $40\%/ans + 10\%/ans$ à partir de 10 ans. + \item Les bébés meurent avec un taux de $65\%/ans \Rightarrow 5\%/mois$ sur 7 mois en moyenne. +\end{itemize} + + +\begin{center} + \includegraphics[width=\textwidth]{rabbit's_rules.png} +\end{center} + +\section{Structure de donnée} +Pour stocker les lapins j'ai choisit de les classées par âge. En effet +toute les règles sont basé sur l'âge alors je peux les compter. Ma +structure de données est donc basé sur cela. J'ai un tableau par sexe +et l'indice du tableau correspond a l'âge. J'ai aussi le nombre de lapine +en gestation. Pour les bébés j'ai exactement la même chose sauf que +l indice représente le mois plutôt que l'année. Pour les nombres j'ai +choisi un entier non-signé de 128 bits (ce qui est pas disponible pour +toute les plateformes) pour évité un maximum les dépassement d'entier. + +\begin{verbatim} +#define N_MATURE (16) +#define N_KITTEN (8) + typedef struct rabbit_hole_s { + __uint128_t male_mature[N_MATURE]; + __uint128_t female_mature[N_MATURE]; + __uint128_t female_litter; + __uint128_t kitten_male[N_KITTEN]; + __uint128_t kitten_female[N_KITTEN]; +} rabbit_hole_t; +\end{verbatim} + +\end{document} \ No newline at end of file diff --git a/repport/images/draw_rabbit.jpg b/repport/images/draw_rabbit.jpg new file mode 100644 index 0000000..1fb725b --- /dev/null +++ b/repport/images/draw_rabbit.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a30cebbbfbafb63b6b9336007d14c10be9aa194f3582648a95d28d577bdd4e3b +size 1406621 diff --git a/repport/images/rabbit's_rules.png b/repport/images/rabbit's_rules.png new file mode 100644 index 0000000..579ba19 --- /dev/null +++ b/repport/images/rabbit's_rules.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b24cf9c89d6b3dedcaedeff47c1b93a5420549475db97b953d57ab9e1b8b3dc5 +size 45381 diff --git a/repport/rabbit's_rules.png b/repport/rabbit's_rules.png new file mode 100644 index 0000000..579ba19 --- /dev/null +++ b/repport/rabbit's_rules.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b24cf9c89d6b3dedcaedeff47c1b93a5420549475db97b953d57ab9e1b8b3dc5 +size 45381