8000 GitHub - ariasdiniz/advanced_math_lib: A C library with useful mathematical functions
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

ariasdiniz/advanced_math_lib

Repository files navigation

libamath - Advanced Math Library

libamath is a C library that provides advanced mathematical functions, with a focus on algorithms for statistical analysis and genetic algorithms. The library is optimized for performance, with multithreaded implementations for various distributions and transforms, making it suitable for computationally intensive tasks. It is originaly built to compile with GNU C 17, but should be compatible with any GNU C version.

Features

Genetic Algorithms

  • Individuals generation: Create a population of individuals, each with a set of weights. Includes mutation and reproduction mechanisms.
  • Reproduction: Replaces low-fitness individuals by reproducing the best-performing individuals, using the mean of their weights.
  • Mutation: Randomly alters the weights of individuals based on a mutation probability.
  • Fitness evaluation: A user-defined function to evaluate the fitness of each individual in the population.

Statistical Functions

  • Mean: Calculate the mean of a dataset. Returns NAN on error (NULL pointer or zero length).
  • Median: Compute the median of a dataset, with an option to pre-sort the data. Returns NAN on error.
  • Standard Deviation: Compute the population or sample standard deviation. Returns NAN on error.
  • Covariance: Measure how two datasets vary together. Returns NAN on error.
  • Variance: Calculates the variance of a dataset. Returns NAN on error.
  • Pearson Correlation: Calculate the Pearson correlation coefficient (r ∈ [−1, +1]). Returns NAN on error.
  • Kendall's Tau: Calculate the Kendall rank correlation coefficient between two datasets.
  • Min: Return the smallest value in the array. Returns NAN on error.
  • Max: Return the largest value in the array. Returns NAN on error.
  • Range: Calculate the range of a dataset (max - min). Returns NAN on error.
  • Normalize: Normalize a dataset to a specified range, using min-max normalization. Does not normalize if Range is zero or Range or Min are NAN.
  • Z-Score: Calculates the Z-Score (Standard Score) for every element of a dataset. Returns a new array with the zscore of each element, or NULL on error.

Discrete Fourier Transform (DFT)

  • DFT: Perform a Discrete Fourier Transform on a dataset, with multithreading support for faster execution.
  • Inverse DFT: Perform an inverse DFT to revert transformed data back to the time domain.

Probability Distributions

  • Normal Distribution: Calculate the normal distribution values of a dataset, optimized with multithreading.
  • Poisson Distribution: Compute the Poisson distribution of a discrete dataset, also supporting multithreading.

Linear Algebra

  • Dot Product: Calculate the dot product between two same sized arrays.
  • Cross Product: Calculate the cross product between two arrays with three elements, returnung a new array.

Future Work

Planned enhancements:

Functions related to linear algebra, calculus and differential equations will be implemented in the future.

Installation

To use libamath, simply clone this repository and include the source files in your project. The library is licensed under the MIT license, so you are free to use, modify, and distribute it in your own projects. When using libamath don't forget to link -lamath -lm during compilation.

git clone git@github.com:ariasdiniz/advanced_math_lib.git

If you want to install it in your UNIX system you can use the install.sh script. It needs superuser access and GCC compiler instaled.

If you have Make installed, you can also build with

make

This way you will build the lib's Shared Object and also an executable called amath. This executable is a simple command line tool to run functions like stdev, mean, ndist and median in a stream of data read from STDIN.

Usage

Here’s a simple example of how to use the genetic algorithm functionality in libamath:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <amath.h>

/*
  This code aims to demonstrate the functioning of the genetic algorithm.

  For this, we have the following problem:

  We have a basket that can carry 8 kg, and we have a set of 4 products.
  Their weights are 3 kg, 4 kg, 5kg and 8 kg, represented by the algorithm's
  weights 0, 1, 2 and 3 respectively.

  The problem is to determine the number of unique products
  this basket can carry. The response is 2 items, one that wights 3 kg
  and another that weights 5 kg. Or it could be only the item with 8 kg.

  For this problem, the best fitted individuals of the algorithm
  have to have, after training, weights like:

  0 => between 0.2 and 1
  1 => approximately 0
  2 => between 0.2 and 1
  3 => approximately 0

  OR

  0 => approximately 0
  1 => approximately 0
  2 => approximately 0
  3 => between 0.2 and 1

  For better results, increase the number of individuals and the
  number of iterations, at the cost of greater computing time.
*/

void *fun(Individuals *individuals) {
  double result = 0;
  int array_size = individuals->n_individuals;
  Individual **individual = individuals->individual_array;
  for (int i = 0; i < array_size; i++) {
    if (individual[i]->weights[0] >= 0.01) result += 3;
    if (individual[i]->weights[1] >= 0.01) result += 4;
    if (individual[i]->weights[2] >= 0.01) result += 5;
    if (individual[i]->weights[3] >= 0.01) result += 8;
    if (result > 8 || result <= 0 ) {
      individual[i]->fitness = 0.0;
      result = 0;
      continue;
    }
    individual[i]->fitness = result;
    result = 0;
  }
  return NULL;
}

int main(int argc, char *argv[]) {
  srand(time(NULL));
  Individuals *individuals = generate_individuals(100000, 0.05, 0.0001, 0.25, 4, 0.0, 1.0);
  for (int i = 0; i < 1000; i++) {
    fit(individuals, fun);
    mutate(individuals);
    reproduce(individuals);
  }
  printf("Individual 
72E2
1, weight 0 : %f\n", individuals->individual_array[0]->weights[0]);
  printf("Individual 1, weight 1 : %f\n", individuals->individual_array[0]->weights[1]);
  printf("Individual 1, weight 2 : %f\n", individuals->individual_array[0]->weights[2]);
  printf("Individual 1, weight 3 : %f\n", individuals->individual_array[0]->weights[3]);
  destroy_individuals(individuals);
  return 0;
}

Another Usage

Here’s an example showing covariance and correlation:

#include <math.h>
#include <stdio.h>
#include "amath.h"

int main() {
    double a[] = {1.0, 2.0, 3.0};
    double b[] = {2.0, 4.0, 6.0};

    double cov = amath_covariance(a, b, 1, 3);
    if (isnan(cov)) {
        return 1;
    }
    printf("Covariance: %f\n", cov);

    double r = amath_pcorr(a, b, 3);
    if (isnan(r)) {
        return 1;
    }
    printf("Pearson r: %f\n", r);

    return 0;
}

CLI Usage

After building, use the amath tool to process data streams:

cat data.txt | amath median

Supported commands:

  • mean, median, stdev, ndist, min, max, range, normalize, zscore, variance

Contributing

Contributions are welcome! Fork the repo and submit a pull request for new features or bug fixes. For issues, please open a GitHub Issue. Feedback and suggestions are always appreciated.

About

A C library with useful mathematical functions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0