Major rework to improve code quality and add automation checks (#805)

* delete secant method - it is identical to regula falsi

* document + improvize root finding algorithms

* attempt to document gaussian elimination

* added file brief

* commented doxygen-mainpage, added files-list link

* corrected files list link path

* files-list link correction - this time works :)

* document successive approximations

* cleaner equation

* updating DIRECTORY.md

* documented kmp string search

* document brute force string search

* document rabin-karp string search

* fixed mainpage readme

* doxygen v1.8.18 will suppress out the #minipage in the markdown

* cpplint correction for header guard style

* github action to auto format source code per cpplint standard

* updated setting to add 1 space before `private` and `public` keywords

* auto rename files and auto format code

* added missing "run" for step

* corrected asignmemt operation

* fixed trim and assign syntax

* added git move for renaming bad filenames

* added missing pipe for trim

* added missing space

* use old and new fnames

* store old fname using echo

* move files only if there is a change in filename

* put old filenames in quotes

* use double quote for old filename

* escape double quotes

* remove old_fname

* try escape characters and echo"

* add file-type to find

* cleanup echo

* ensure all trim variables are also in quotes

* try escape -quote again

* remove second escpe quote

* use single quote for first check

* use carets instead of quotes

* put variables in brackets

* remove -e from echo

* add debug echos

* try print0 flag

* find command with while instead of for-loop

* find command using IFS instead

* 🎉 IFS fix worked - escaped quotes for git mv

* protetc each word in git mv ..

* filename exists in lower cases - renamed

* 🎉 git push enabled

* updating DIRECTORY.md

* git pull & then push

* formatting filenames d7af6fdc8c

* formatting source-code for d7af6fdc8c

* remove allman break before braces

* updating DIRECTORY.md

* added missing comma lost in previous commit

* orchestrate all workflows

* fix yml indentation

* force push format changes, add title to DIRECTORY.md

* pull before proceeding

* reorganize pull commands

* use master branches for actions

* rename .cc files to .cpp

* added class destructor to clean up dynamic memory allocation

* rename to awesome workflow

* commented whole repo cpplint - added modified files lint check

* removed need for cpplint

* attempt to use actions/checkout@master

* temporary: no dependency on cpplint

* formatting filenames 153fb7b8a5

* formatting source-code for 153fb7b8a5

* updating DIRECTORY.md

* fix diff filename

* added comments to the code

* added test case

* formatting source-code for a850308fba

* updating DIRECTORY.md

* added machine learning folder

* added adaline algorithm

* updating DIRECTORY.md

* fixed issue [LWG2192](https://cplusplus.github.io/LWG/issue2192) for std::abs on MacOS

* add cmath for same bug: [LWG2192](https://cplusplus.github.io/LWG/issue2192) for std::abs on MacOS

* formatting source-code for f8925e4822

* use STL's inner_product

* formatting source-code for f94a330594

* added range comments

* define activation function

* use equal initial weights

* change test2 function to predict

* activation function not friend

* previous commit correction

* added option for predict function to return value before applying activation function as optional argument

* added test case to classify points lying within a sphere

* improve documentation for adaline

* formatting source-code for 15ec4c3aba

* added cmake to geometry folder

* added algorithm include for std::max

* add namespace - machine_learning

* add namespace - statistics

* add namespace - sorting

* added sorting algos to namespace sorting

* added namespace string_search

* formatting source-code for fd69530515

* added documentation to string_search namespace

* feat: Add BFS and DFS algorithms to check for cycle in a directed graph

* Remove const references for input of simple types

Reason: overhead on access

* fix bad code

sorry for force push

* Use pointer instead of the non-const reference

because apparently google says so.

* Remove a useless and possibly bad Graph constuctor overload

* Explicitely specify type of vector during graph instantiation

* updating DIRECTORY.md

* find openMP before adding subdirectories

* added kohonen self organizing map

* updating DIRECTORY.md

* remove older files and folders from gh-pages before adding new files

* remove chronos library due to inacceptability by cpplint

* use c++ specific static_cast instead

* initialize radom number generator

* updated image links with those from CPP repository

* rename computer.... folder to numerical methods

* added durand kerner method for root computation for arbitrarily large polynomials

* fixed additional comma

* fix cpplint errors

* updating DIRECTORY.md

* convert to function module

* update documentation

* move openmp to main loop

* added two test cases

* use INT16_MAX

* remove return statement from omp-for loop and use "break"

* run tests when no input is provided and skip tests when input polynomial is provided

* while loop cannot have break - replaced with continue and check is present in the main while condition

* (1) break while loop (2) skip runs on break_loop instead of hard-break

* add documentation images

* use long double for errors and tolerance checks

* make iterator variable i local to threads

* add critical secions to omp threads

* bugfix: move file writing outside of the parallel loop
othersie, there is no gurantee of the order of roots written to file

* rename folder to data_structures

* updating DIRECTORY.md

* fix ambiguous symbol `size`

* add data_structures to cmake

* docs: enable tree view, add timestamp in footer, try clang assistaed parsing

* doxygen - open links in external window

* remove invalid parameter from function docs

* use HTML5 img tag to resize images

* move file to proper folder

* fix documentations and cpplint

* formatting source-code for aacaf9828c

* updating DIRECTORY.md

* cpplint: add braces for multiple statement if

* add explicit link to badges

* remove  duplicate line

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* remove namespace indentation

* remove file associations in settings

* add author name

* enable cmake in subfolders of data_structures

* create and link object file

* cpp lint fixes and instantiate template classes

* cpp lint fixes and instantiate template classes

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* cpplint - ignore `build/include`

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* disable redundant gcc compilation in cpplint workflow

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* template header files contain function codes as well and removed redundant subfolders

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* updating DIRECTORY.md

* remove semicolons after functions in a class

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* cpplint header guard style

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* remove semilon

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* added LU decomposition algorithm

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* added QR decomposition algorithm

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* use QR decomposition to find eigen values

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* updating DIRECTORY.md

* use std::rand for thread safety

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* move srand to main()

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* cpplint braces correction

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* updated eigen value documentation

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* fix matrix shift doc

Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

* rename CONTRIBUTION.md to CONTRIBUTING.md #836

* remove 'sort alphabetical order' check

* added documentation check

* remove extra paranthesis

* added gitpod

* added gitpod link from README

* attempt to add vscode gitpod extensions

* update gitpod extensions

* add gitpod extensions cmake-tools and git-graph

* remove gitpod init and add commands

* use init to one time install doxygen, graphviz, cpplint

* use gitpod dockerfile

* add ninja build system to docker

* remove configure task

* add github prebuild specs to gitpod

* disable gitpod addcommit

* update documentation for kohonen_som

* added ode solve using forward euler method

* added mid-point euler ode solver

* fixed itegration step equation

* added semi-implicit euler ODE solver

* updating DIRECTORY.md

* fix cpplint issues - lines 117 and 124

* added documentation to ode group

* corrected semi-implicit euler function

* updated docs and test cases better structure

* replace `free` with `delete` operator

* formatting source-code for f55ab50cf2

* updating DIRECTORY.md

* main function must return

* added machine learning group

* added kohonen som topology algorithm

* fix graph image path

* updating DIRECTORY.md

* fix braces

* use snprintf instead of sprintf

* use static_cast

* hardcode character buffer size

* fix machine learning groups in documentation

* fix missing namespace function

* replace kvedala fork references to TheAlgorithms

* fix bug in counting_sort

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Anmol3299 <mittalanmol22@gmail.com>
This commit is contained in:
Krishna Vedala
2020-06-19 12:04:56 -04:00
committed by GitHub
parent 70a2aeedc3
commit aaa08b0150
313 changed files with 49332 additions and 9833 deletions

18
math/CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c )
# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES)
foreach( testsourcefile ${APP_SOURCES} )
# I used a simple string replace, to cut off .cpp.
string( REPLACE ".cpp" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX)
if(OpenMP_CXX_FOUND)
target_link_libraries(${testname} OpenMP::OpenMP_CXX)
endif()
install(TARGETS ${testname} DESTINATION "bin/math")
endforeach( testsourcefile ${APP_SOURCES} )

View File

@@ -1,3 +1,4 @@
# Prime factorization # {#section}
Prime Factorization is a very important and useful technique to factorize any number into its prime factors. It has various applications in the field of number theory.
The method of prime factorization involves two function calls.

View File

@@ -1,46 +1,57 @@
/// C++ Program to find Binary Exponent Iteratively and Recursively.
#include<iostream>
/*
* Calculate a^b in O(log(b)) by converting b to a binary number.
* Binary exponentiation is also known as exponentiation by squaring.
* NOTE : This is a far better approach compared to naive method which provide O(b) operations.
/**
* @file
* @brief C++ Program to find Binary Exponent Iteratively and Recursively.
*
* Calculate \f$a^b\f$ in \f$O(\log(b))\f$ by converting \f$b\f$ to a
* binary number. Binary exponentiation is also known as exponentiation by
* squaring.
* @note This is a far better approach compared to naive method which
* provide \f$O(b)\f$ operations.
*
* Example:
* 10 in base 2 is 1010.
* 2^10 = 2^(1010) = 2^8 * 2^2
* 2^1 = 2
* 2^2 = (2^1)^2 = 2^2 = 4
* 2^4 = (2^2)^2 = 4^2 = 16
* 2^8 = (2^4)^2 = 16^2 = 256
* Hence to calculate 2^10 we only need to multiply 2^8 and 2^2 skipping 2^1 and 2^4.
*/
* </br>10 in base 2 is 1010.
* \f{eqnarray*}{
* 2^{10_d} &=& 2^{1010_b} = 2^8 * 2^2\\
* 2^1 &=& 2\\
* 2^2 &=& (2^1)^2 = 2^2 = 4\\
* 2^4 &=& (2^2)^2 = 4^2 = 16\\
* 2^8 &=& (2^4)^2 = 16^2 = 256\\
* \f}
* Hence to calculate 2^10 we only need to multiply \f$2^8\f$ and \f$2^2\f$
* skipping \f$2^1\f$ and \f$2^4\f$.
*/
/// Recursive function to calculate exponent in O(log(n)) using binary exponent.
#include <iostream>
/// Recursive function to calculate exponent in \f$O(\log(n))\f$ using binary
/// exponent.
int binExpo(int a, int b) {
if (b == 0) {
return 1;
}
int res = binExpo(a, b/2);
if (b%2) {
return res*res*a;
int res = binExpo(a, b / 2);
if (b % 2) {
return res * res * a;
} else {
return res*res;
return res * res;
}
}
/// Iterative function to calculate exponent in O(log(n)) using binary exponent.
/// Iterative function to calculate exponent in \f$O(\log(n))\f$ using binary
/// exponent.
int binExpo_alt(int a, int b) {
int res = 1;
while (b > 0) {
if (b%2) {
res = res*a;
if (b % 2) {
res = res * a;
}
a = a*a;
a = a * a;
b /= 2;
}
return res;
}
/// Main function
int main() {
int a, b;
/// Give two numbers a, b

View File

@@ -1,22 +1,24 @@
/**
* Copyright 2020 @author omkarlanghe
*
* @file
* @file
* A simple program to check if the given number if prime or not.
*
*
* @brief
* Reduced all possibilities of a number which cannot be prime.
* Eg: No even number, except 2 can be a prime number, hence we will increment our loop with i+2 jumping on all odd numbers only.
* If number is <= 1 or if it is even except 2, break the loop and return false telling number is not prime.
* Eg: No even number, except 2 can be a prime number, hence we will increment
* our loop with i+2 jumping on all odd numbers only. If number is <= 1 or if it
* is even except 2, break the loop and return false telling number is not
* prime.
*/
#include <iostream>
#include <cassert>
/**
#include <iostream>
/**
* Function to check if the given number is prime or not.
* @param num number to be checked.
* @return if number is prime, it returns @ true, else it returns @ false.
*/
template<typename T>
template <typename T>
bool is_prime(T num) {
bool result = true;
if (num <= 1) {
@@ -27,7 +29,7 @@ bool is_prime(T num) {
return 0;
}
if (num >= 3) {
for (T i = 3 ; (i*i) < (num) ; i = (i + 2)) {
for (T i = 3; (i * i) < (num); i = (i + 2)) {
if ((num % i) == 0) {
result = false;
break;
@@ -41,18 +43,19 @@ bool is_prime(T num) {
* Main function
*/
int main() {
// perform self-test
assert(is_prime(50) == false);
assert(is_prime(115249) == true);
int num;
std::cout << "Enter the number to check if it is prime or not" <<
std::endl;
std::cout << "Enter the number to check if it is prime or not" << std::endl;
std::cin >> num;
bool result = is_prime(num);
if (result) {
std::cout << num << " is a prime number" <<
std::endl;
std::cout << num << " is a prime number" << std::endl;
} else {
std::cout << num << " is not a prime number" <<
std::endl;
std::cout << num << " is not a prime number" << std::endl;
}
assert(is_prime(50) == false);
assert(is_prime(115249) == true);
return 0;
}

View File

@@ -1,28 +1,41 @@
#include <iostream>
/**
* @file
* @brief Compute double factorial: \f$n!!\f$
*
* Double factorial of a non-negative integer n, is defined as the product of
* all the integers from 1 to n that have the same parity (odd or even) as n.
* <br/>It is also called as semifactorial of a number and is denoted by
* \f$n!!\f$
*/
#include <cassert>
#include <iostream>
/* Double factorial of a non-negative integer n, is defined as the product of
all the integers from 1 to n that have the same parity (odd or even) as n.
It is also called as semifactorial of a number and is denoted by !! */
/** Compute double factorial using iterative method
*/
uint64_t double_factorial_iterative(uint64_t n) {
uint64_t res = 1;
for ( uint64_t i = n; i >= 0; i -= 2 ) {
if (i == 0 || i == 1) return res;
res *= i;
}
uint64_t res = 1;
for (uint64_t i = n;; i -= 2) {
if (i == 0 || i == 1)
return res;
res *= i;
}
return res;
}
/* Recursion can be costly for large numbers */
/** Compute double factorial using resursive method.
* <br/>Recursion can be costly for large numbers.
*/
uint64_t double_factorial_recursive(uint64_t n) {
if (n <= 1) return 1;
return n * double_factorial_recursive(n - 2);
if (n <= 1)
return 1;
return n * double_factorial_recursive(n - 2);
}
/// main function
int main() {
uint64_t n{};
std::cin >> n;
assert(n >= 0);
std::cout << double_factorial_iterative(n);
uint64_t n;
std::cin >> n;
assert(n >= 0);
std::cout << double_factorial_iterative(n);
}

View File

@@ -1,28 +1,37 @@
/// C++ Program to find Euler Totient Function
#include<iostream>
/*
/**
* @file
* @brief C++ Program to find
* [Euler's Totient](https://en.wikipedia.org/wiki/Euler%27s_totient_function)
* function
*
* Euler Totient Function is also known as phi function.
* phi(n) = phi(p1^a1).phi(p2^a2)...
* where p1, p2,... are prime factors of n.
* 3 Euler's properties:
* 1. phi(prime_no) = prime_no-1
* 2. phi(prime_no^k) = (prime_no^k - prime_no^(k-1))
* 3. phi(a,b) = phi(a). phi(b) where a and b are relative primes.
* \f[\phi(n) =
* \phi\left({p_1}^{a_1}\right)\cdot\phi\left({p_2}^{a_2}\right)\ldots\f] where
* \f$p_1\f$, \f$p_2\f$, \f$\ldots\f$ are prime factors of n.
* <br/>3 Euler's properties:
* 1. \f$\phi(n) = n-1\f$
* 2. \f$\phi(n^k) = n^k - n^{k-1}\f$
* 3. \f$\phi(a,b) = \phi(a)\cdot\phi(b)\f$ where a and b are relative primes.
*
* Applying this 3 properties on the first equation.
* phi(n) = n. (1-1/p1). (1-1/p2). ...
* where p1,p2... are prime factors.
* Hence Implementation in O(sqrt(n)).
* phi(100) = 40
* phi(1) = 1
* phi(17501) = 15120
* phi(1420) = 560
* \f[\phi(n) =
* n\cdot\left(1-\frac{1}{p_1}\right)\cdot\left(1-\frac{1}{p_2}\right)\cdots\f]
* where \f$p_1\f$,\f$p_2\f$... are prime factors.
* Hence Implementation in \f$O\left(\sqrt{n}\right)\f$.
* <br/>Some known values are:
* * \f$\phi(100) = 40\f$
* * \f$\phi(1) = 1\f$
* * \f$\phi(17501) = 15120\f$
* * \f$\phi(1420) = 560\f$
*/
#include <cstdlib>
#include <iostream>
// Function to caculate Euler's totient phi
int phiFunction(int n) {
int result = n;
for (int i = 2; i * i <= n; i++) {
/** Function to caculate Euler's totient phi
*/
uint64_t phiFunction(uint64_t n) {
uint64_t result = n;
for (uint64_t i = 2; i * i <= n; i++) {
if (n % i == 0) {
while (n % i == 0) {
n /= i;
@@ -30,12 +39,20 @@ int phiFunction(int n) {
result -= result / i;
}
}
if (n > 1) result -= result / n;
if (n > 1)
result -= result / n;
return result;
}
int main() {
int n;
/// Main function
int main(int argc, char *argv[]) {
uint64_t n;
if (argc < 2) {
std::cout << "Enter the number: ";
} else {
n = strtoull(argv[1], nullptr, 10);
}
std::cin >> n;
std::cout << phiFunction(n);
return 0;
}

View File

@@ -1,28 +1,96 @@
/**
* @file
* @brief GCD using [extended Euclid's algorithm]
* (https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)
*
* Finding coefficients of a and b ie x and y in Bézout's identity
* \f[\text{gcd}(a, b) = a \times x + b \times y \f]
* This is also used in finding Modular
* multiplicative inverse of a number. (A * B)%M == 1 Here B is the MMI of A for
* given M, so extendedEuclid (A, M) gives B.
*/
#include <algorithm> // for swap function
#include <iostream>
// Finding coefficients of a and b ie x and y in gcd(a, b) = a * x + b * y
// d is gcd(a, b)
// This is also used in finding Modular multiplicative inverse of a number.
// (A * B)%M == 1 Here B is the MMI of A for given M,
// so extendedEuclid (A, M) gives B.
int d, x, y;
void extendedEuclid(int A, int B) {
/**
* function to update the coefficients per iteration
* \f[r_0,\,r = r,\, r_0 - \text{quotient}\times r\f]
*
* @param[in,out] r signed or unsigned
* @param[in,out] r0 signed or unsigned
* @param[in] quotient unsigned
*/
template <typename T, typename T2>
inline void update_step(T *r, T *r0, const T2 quotient) {
T temp = *r;
*r = *r0 - (quotient * temp);
*r0 = temp;
}
/**
* Implementation using iterative algorithm from
* [Wikipedia](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode)
*
* @param[in] A unsigned
* @param[in] B unsigned
* @param[out] GCD unsigned
* @param[out] x signed
* @param[out] y signed
*/
template <typename T1, typename T2>
void extendedEuclid_1(T1 A, T1 B, T1 *GCD, T2 *x, T2 *y) {
if (B > A)
std::swap(A, B); // Ensure that A >= B
T2 s = 0, s0 = 1;
T2 t = 1, t0 = 0;
T1 r = B, r0 = A;
while (r != 0) {
T1 quotient = r0 / r;
update_step(&r, &r0, quotient);
update_step(&s, &s0, quotient);
update_step(&t, &t0, quotient);
}
*GCD = r0;
*x = s0;
*y = t0;
}
/**
* Implementation using recursive algorithm
*
* @param[in] A unsigned
* @param[in] B unsigned
* @param[out] GCD unsigned
* @param[in,out] x signed
* @param[in,out] y signed
*/
template <typename T, typename T2>
void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) {
if (B > A)
std::swap(A, B); // Ensure that A >= B
if (B == 0) {
d = A;
x = 1;
y = 0;
*GCD = A;
*x = 1;
*y = 0;
} else {
extendedEuclid(B, A%B);
int temp = x;
x = y;
y = temp - (A/B)*y;
extendedEuclid(B, A % B, GCD, x, y);
T2 temp = *x;
*x = *y;
*y = temp - (A / B) * (*y);
}
}
/// Main function
int main() {
int a, b;
uint32_t a, b, gcd;
int32_t x, y;
std::cin >> a >> b;
extendedEuclid(a, b);
std::cout << x << " " << y << std::endl;
extendedEuclid(a, b, &gcd, &x, &y);
std::cout << gcd << " " << x << " " << y << std::endl;
extendedEuclid_1(a, b, &gcd, &x, &y);
std::cout << gcd << " " << x << " " << y << std::endl;
return 0;
}

View File

@@ -1,14 +1,17 @@
// C++ program to find factorial of given number
#include<iostream>
/**
* @file
* @brief C++ program to find factorial of given number
*/
#include <iostream>
// function to find factorial of given number
/** function to find factorial of given number */
unsigned int factorial(unsigned int n) {
if (n == 0)
return 1;
return n * factorial(n - 1);
}
// Driver code
/** Main function */
int main() {
int num = 5;
std::cout << "Factorial of " << num << " is " << factorial(num)

View File

@@ -1,29 +1,40 @@
#include <iostream>
#include <cstdlib>
#include <cstdint>
/**
* @file
* @brief Faster computation for \f$a^b\f$
*
* Program that computes \f$a^b\f$ in \f$O(logN)\f$ time.
* It is based on formula that:
* 1. if \f$b\f$ is even:
* \f$a^b = a^\frac{b}{2} \cdot a^\frac{b}{2} = {a^\frac{b}{2}}^2\f$
* 2. if \f$b\f$ is odd: \f$a^b = a^\frac{b-1}{2}
* \cdot a^\frac{b-1}{2} \cdot a = {a^\frac{b-1}{2}}^2 \cdot a\f$
*
* We can compute \f$a^b\f$ recursively using above algorithm.
*/
#include <cassert>
#include <ctime>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <iostream>
/*
Program that computes a^b in O(logN) time.
It is based on formula that:
case1) if b is even: a^b = a^(b/2) * a^(b/2) = (a^(b/2))ˆ2
case2) if b is odd: a^b = a^((b-1)/2) * a^((b-1)/2) * a = (a^((b-1)/2))^2 * a
We can compute a^b recursively using above algorithm.
*/
double fast_power_recursive(int64_t a, int64_t b) {
/**
* algorithm implementation for \f$a^b\f$
*/
template <typename T>
double fast_power_recursive(T a, T b) {
// negative power. a^b = 1 / (a^-b)
if (b < 0)
return 1.0 / fast_power_recursive(a, -b);
if (b == 0) return 1;
int64_t bottom = fast_power_recursive(a, b >> 1);
if (b == 0)
return 1;
T bottom = fast_power_recursive(a, b >> 1);
// Since it is integer division b/2 = (b-1)/2 where b is odd.
// Therefore, case2 is easily solved by integer division.
int64_t result;
double result;
if ((b & 1) == 0) // case1
result = bottom * bottom;
else // case2
@@ -31,49 +42,52 @@ double fast_power_recursive(int64_t a, int64_t b) {
return result;
}
/*
/**
Same algorithm with little different formula.
It still calculates in O(logN)
It still calculates in \f$O(\log N)\f$
*/
double fast_power_linear(int64_t a, int64_t b) {
template <typename T>
double fast_power_linear(T a, T b) {
// negative power. a^b = 1 / (a^-b)
if (b < 0)
return 1.0 / fast_power_linear(a, -b);
double result = 1;
while (b) {
if (b & 1) result = result * a;
if (b & 1)
result = result * a;
a = a * a;
b = b >> 1;
}
return result;
}
/**
* Main function
*/
int main() {
std::srand(time(NULL));
std::srand(std::time(nullptr));
std::ios_base::sync_with_stdio(false);
std::cout << "Testing..." << std::endl;
for (int i = 0; i < 20; i++) {
unsigned int *rand1, *rand2;
int a = rand_r(rand1) % 20 - 10;
int b = rand_r(rand2) % 20 - 10;
int a = std::rand() % 20 - 10;
int b = std::rand() % 20 - 10;
std::cout << std::endl << "Calculating " << a << "^" << b << std::endl;
assert(fast_power_recursive(a, b) == std::pow(a, b));
assert(fast_power_linear(a, b) == std::pow(a, b));
std::cout << "------ " << a << "^" << b << " = "<<
fast_power_recursive(a, b) << std::endl;
std::cout << "------ " << a << "^" << b << " = "
<< fast_power_recursive(a, b) << std::endl;
}
int64_t a, b;
std::cin >> a >> b;
std::cout << a << "^" << b << " = "<<
fast_power_recursive(a, b) << std::endl;
std::cout << a << "^" << b << " = " << fast_power_recursive(a, b)
<< std::endl;
std::cout << a << "^" << b << " = "<<
fast_power_linear(a, b) << std::endl;
std::cout << a << "^" << b << " = " << fast_power_linear(a, b) << std::endl;
return 0;
}

View File

@@ -1,22 +1,30 @@
#include <iostream>
/**
* @file
* @brief Generate fibonacci sequence
*
* Calculate the the value on Fibonacci's sequence given an
* integer as input.
* \f[\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)\f]
*
* @see fibonacci_large.cpp, fibonacci_fast.cpp, string_fibonacci.cpp
*/
#include <cassert>
#include <iostream>
/* Calculate the the value on Fibonacci's sequence given an
integer as input
Fibonacci = 0, 1, 1, 2, 3, 5,
8, 13, 21, 34, 55,
89, 144, ... */
int fibonacci(uint n) {
/**
* Recursively compute sequences
*/
int fibonacci(unsigned int n) {
/* If the input is 0 or 1 just return the same
This will set the first 2 values of the sequence */
if (n <= 1)
return n;
/* Add the last 2 values of the sequence to get next */
return fibonacci(n-1) + fibonacci(n-2);
return fibonacci(n - 1) + fibonacci(n - 2);
}
/// Main function
int main() {
int n;
std::cin >> n;

53
math/fibonacci_fast.cpp Normal file
View File

@@ -0,0 +1,53 @@
/**
* @file
* @brief Faster computation of Fibonacci series
*
* An efficient way to calculate nth fibonacci number faster and simpler than
* \f$O(n\log n)\f$ method of matrix exponentiation This works by using both
* recursion and dynamic programming. as 93rd fibonacci exceeds 19 digits, which
* cannot be stored in a single long long variable, we can only use it till 92nd
* fibonacci we can use it for 10000th fibonacci etc, if we implement
* bigintegers. This algorithm works with the fact that nth fibonacci can easily
* found if we have already found n/2th or (n+1)/2th fibonacci It is a property
* of fibonacci similar to matrix exponentiation.
*
* \author [Krishna Vedala](https://github.com/kvedala)
* @see fibonacci_large.cpp, fibonacci.cpp, string_fibonacci.cpp
*/
#include <cinttypes>
#include <cstdio>
#include <iostream>
/** maximum number that can be computed - The result after 93 cannot be stored
* in a `uint64_t` data type. */
const uint64_t MAX = 93;
/** Array of computed fibonacci numbers */
uint64_t f[MAX] = {0};
/** Algorithm */
uint64_t fib(uint64_t n) {
if (n == 0)
return 0;
if (n == 1 || n == 2)
return (f[n] = 1);
if (f[n])
return f[n];
uint64_t k = (n % 2 != 0) ? (n + 1) / 2 : n / 2;
f[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1))
: (2 * fib(k - 1) + fib(k)) * fib(k);
return f[n];
}
/** Main function */
int main() {
// Main Function
for (uint64_t i = 1; i < 93; i++) {
std::cout << i << " th fibonacci number is " << fib(i) << std::endl;
}
return 0;
}

85
math/fibonacci_large.cpp Normal file
View File

@@ -0,0 +1,85 @@
/**
* @file
* @brief Computes N^th Fibonacci number given as
* input argument. Uses custom build arbitrary integers library
* to perform additions and other operations.
*
* Took 0.608246 seconds to compute 50,000^th Fibonacci
* number that contains 10450 digits!
*
* \author [Krishna Vedala](https://github.com/kvedala)
* @see fibonacci.cpp, fibonacci_fast.cpp, string_fibonacci.cpp
*/
#include <cinttypes>
#include <ctime>
#include <iostream>
#include "./large_number.h"
/** Compute fibonacci numbers using the relation
* \f[f(n)=f(n-1)+f(n-2)\f]
* and returns the result as a large_number type.
*/
large_number fib(uint64_t n) {
large_number f0(1);
large_number f1(1);
do {
large_number f2 = f1;
f1 += f0;
f0 = f2;
n--;
} while (n > 2); // since we start from 2
return f1;
}
int main(int argc, char *argv[]) {
uint64_t N;
if (argc == 2) {
N = strtoull(argv[1], NULL, 10);
} else {
std::cout << "Enter N: ";
std::cin >> N;
}
clock_t start_time = std::clock();
large_number result = fib(N);
clock_t end_time = std::clock();
double time_taken = static_cast<double>(end_time - start_time) /
static_cast<double>(CLOCKS_PER_SEC);
std::cout << std::endl
<< N << "^th Fibonacci number: " << result << std::endl
<< "Number of digits: " << result.num_digits() << std::endl
<< "Time taken: " << std::scientific << time_taken << " s"
<< std::endl;
N = 5000;
if (fib(N) ==
large_number(
"387896845438832563370191630832590531208212771464624510616059721489"
"555013904403709701082291646221066947929345285888297381348310200895"
"498294036143015691147893836421656394410691021450563413370655865623"
"825465670071252592990385493381392883637834751890876297071203333705"
"292310769300851809384980180384781399674888176555465378829164426891"
"298038461377896902150229308247566634622492307188332480328037503913"
"035290330450584270114763524227021093463769910400671417488329842289"
"149127310405432875329804427367682297724498774987455569190770388063"
"704683279481135897373999311010621930814901857081539785437919530561"
"751076105307568878376603366735544525884488624161921055345749367589"
"784902798823435102359984466393485325641195222185956306047536464547"
"076033090242080638258492915645287629157575914234380914230291749108"
"898415520985443248659407979357131684169286803954530954538869811466"
"508206686289742063932343848846524098874239587380197699382031717420"
"893226546887936400263079778005875912967138963421425257911687275560"
"0360311370547754724604639987588046985178408674382863125"))
std::cout << "Test for " << N << "^th Fibonacci number passed!"
<< std::endl;
else
std::cerr << "Test for " << N << "^th Fibonacci number failed!"
<< std::endl;
return 0;
}

View File

@@ -1,10 +1,17 @@
#include <cmath>
/**
* @file
* @brief Compute the greatest common denominator of two integers using
* *iterative form* of
* [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm)
*
* @see gcd_recursive_euclidean.cpp, gcd_of_n_numbers.cpp
*/
#include <iostream>
#include <stdexcept>
// will find the greatest common denominator of two ints integers
// Euclidean algorithm can be found here
// https://en.wikipedia.org/wiki/Euclidean_algorithm
/**
* algorithm
*/
int gcd(int num1, int num2) {
if (num1 <= 0 | num2 <= 0) {
throw std::domain_error("Euclidean algorithm domain is for ints > 0");
@@ -34,6 +41,9 @@ int gcd(int num1, int num2) {
return previous_remainder;
}
/**
* Main function
*/
int main() {
std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl;
try {

41
math/gcd_of_n_numbers.cpp Normal file
View File

@@ -0,0 +1,41 @@
/**
* @file
* @brief This program aims at calculating the GCD of n numbers by division
* method
*
* @see gcd_iterative_euclidean.cpp, gcd_recursive_euclidean.cpp
*/
#include <iostream>
/** Compute GCD using division algorithm
*
* @param[in] a array of integers to compute GCD for
* @param[in] n number of integers in array `a`
*/
int gcd(int *a, int n) {
int j = 1; // to access all elements of the array starting from 1
int gcd = a[0];
while (j < n) {
if (a[j] % gcd == 0) // value of gcd is as needed so far
j++; // so we check for next element
else
gcd = a[j] % gcd; // calculating GCD by division method
}
return gcd;
}
/** Main function */
int main() {
int n;
std::cout << "Enter value of n:" << std::endl;
std::cin >> n;
int *a = new int[n];
int i;
std::cout << "Enter the n numbers:" << std::endl;
for (i = 0; i < n; i++) std::cin >> a[i];
std::cout << "GCD of entered n numbers:" << gcd(a, n) << std::endl;
delete[] a;
return 0;
}

View File

@@ -0,0 +1,52 @@
/**
* @file
* @brief Compute the greatest common denominator of two integers using
* *recursive form* of
* [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm)
*
* @see gcd_iterative_euclidean.cpp, gcd_of_n_numbers.cpp
*/
#include <iostream>
/**
* algorithm
*/
int gcd(int num1, int num2) {
if (num1 <= 0 | num2 <= 0) {
throw std::domain_error("Euclidean algorithm domain is for ints > 0");
}
if (num1 == num2) {
return num1;
}
// Everything divides 0
if (num1 == 0)
return num2;
if (num2 == 0)
return num1;
// base case
if (num1 == num2)
return num1;
// a is greater
if (num1 > num2)
return gcd(num1 - num2, num2);
return gcd(num1, num2 - num1);
}
/**
* Main function
*/
int main() {
std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl;
try {
std::cout << "gcd of -120,10 is " << gcd(-120, 10) << std::endl;
} catch (const std::domain_error &e) {
std::cout << "Error handling was successful" << std::endl;
}
std::cout << "gcd of 312,221 is " << (gcd(312, 221)) << std::endl;
std::cout << "gcd of 289,204 is " << (gcd(289, 204)) << std::endl;
return 0;
}

View File

@@ -1,27 +0,0 @@
// C++ program to find GCD of two numbers
#include <iostream>
// Recursive function to return gcd of a and b
int gcd(int a, int b) {
// Everything divides 0
if (a == 0)
return b;
if (b == 0)
return a;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a-b, b);
return gcd(a, b-a);
}
// Driver program to test above function
int main() {
int a = 98, b = 56;
std::cout << "GCD of " << a << " and " << b << " is " << gcd(a, b);
return 0;
}

118
math/large_factorial.cpp Normal file
View File

@@ -0,0 +1,118 @@
/**
* @file
* @brief Compute factorial of any arbitratily large number/
*
* \author [Krishna Vedala](https://github.com/kvedala)
* @see factorial.cpp
*/
#include <cstring>
#include <ctime>
#include <iostream>
#include "./large_number.h"
/** Test implementation for 10! Result must be 3628800.
* @returns True if test pass else False
*/
bool test1() {
std::cout << "---- Check 1\t";
unsigned int i, number = 10;
large_number result;
for (i = 2; i <= number; i++) /* Multiply every number from 2 thru N */
result *= i;
const char *known_reslt = "3628800";
/* check 1 */
if (strlen(known_reslt) != result.num_digits()) {
std::cerr << "Result lengths dont match! " << strlen(known_reslt)
<< " != " << result.num_digits() << std::endl;
return false;
}
const size_t N = result.num_digits();
for (i = 0; i < N; i++) {
if (known_reslt[i] != result.digit_char(i)) {
std::cerr << i << "^th digit mismatch! " << known_reslt[i]
<< " != " << result.digit_char(i) << std::endl;
return false;
}
}
std::cout << "Passed!" << std::endl;
return true;
}
/** Test implementation for 100! The result is the 156 digit number:
* ```
* 9332621544394415268169923885626670049071596826438162146859296389521759
* 9993229915608941463976156518286253697920827223758251185210916864000000
* 000000000000000000
* ```
* @returns True if test pass else False
*/
bool test2() {
std::cout << "---- Check 2\t";
unsigned int i, number = 100;
large_number result;
for (i = 2; i <= number; i++) /* Multiply every number from 2 thru N */
result *= i;
const char *known_reslt =
"9332621544394415268169923885626670049071596826438162146859296389521759"
"9993229915608941463976156518286253697920827223758251185210916864000000"
"000000000000000000";
/* check 1 */
if (strlen(known_reslt) != result.num_digits()) {
std::cerr << "Result lengths dont match! " << strlen(known_reslt)
<< " != " << result.num_digits() << std::endl;
return false;
}
const size_t N = result.num_digits();
for (i = 0; i < N; i++) {
if (known_reslt[i] != result.digit_char(i)) {
std::cerr << i << "^th digit mismatch! " << known_reslt[i]
<< " != " << result.digit_char(i) << std::endl;
return false;
}
}
std::cout << "Passed!" << std::endl;
return true;
}
/**
* Main program
**/
int main(int argc, char *argv[]) {
int number, i;
if (argc == 2) {
number = atoi(argv[1]);
} else {
std::cout << "Enter the value of n(n starts from 0 ): ";
std::cin >> number;
}
large_number result;
std::clock_t start_time = std::clock();
for (i = 2; i <= number; i++) /* Multiply every number from 2 thru N */
result *= i;
std::clock_t end_time = std::clock();
double time_taken =
static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC;
std::cout << number << "! = " << result << std::endl
<< "Number of digits: " << result.num_digits() << std::endl
<< "Time taken: " << std::scientific << time_taken << " s"
<< std::endl;
test1();
test2();
result.test();
return 0;
}

288
math/large_number.h Normal file
View File

@@ -0,0 +1,288 @@
/**
* @file
* @brief Library to perform arithmatic operations on arbitrarily large
* numbers.
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#ifndef MATH_LARGE_NUMBER_H_
#define MATH_LARGE_NUMBER_H_
#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstring>
#include <iostream>
#include <type_traits>
#include <vector>
/**
* Store large unsigned numbers as a C++ vector
* The class provides convenience functions to add a
* digit to the number, perform multiplication of
* large number with long unsigned integers.
**/
class large_number {
public:
/**< initializer with value = 1 */
large_number() { _digits.push_back(1); }
// /**< initializer from an integer */
// explicit large_number(uint64_t n) {
// uint64_t carry = n;
// do {
// add_digit(carry % 10);
// carry /= 10;
// } while (carry != 0);
// }
/**< initializer from an integer */
explicit large_number(int n) {
int carry = n;
do {
add_digit(carry % 10);
carry /= 10;
} while (carry != 0);
}
/**< initializer from another large_number */
large_number(const large_number &a) : _digits(a._digits) {}
/**< initializer from a vector */
explicit large_number(std::vector<unsigned char> &vec) : _digits(vec) {}
/**< initializer from a string */
explicit large_number(char const *number_str) {
for (size_t i = strlen(number_str); i > 0; i--) {
unsigned char a = number_str[i - 1] - '0';
if (a >= 0 && a <= 9)
_digits.push_back(a);
}
}
/**
* Function to check implementation
**/
static bool test() {
std::cout << "------ Checking `large_number` class implementations\t"
<< std::endl;
large_number a(40);
// 1. test multiplication
a *= 10;
if (a != large_number(400)) {
std::cerr << "\tFailed 1/6 (" << a << "!=400)" << std::endl;
return false;
}
std::cout << "\tPassed 1/6...";
// 2. test compound addition with integer
a += 120;
if (a != large_number(520)) {
std::cerr << "\tFailed 2/6 (" << a << "!=520)" << std::endl;
return false;
}
std::cout << "\tPassed 2/6...";
// 3. test compound multiplication again
a *= 10;
if (a != large_number(5200)) {
std::cerr << "\tFailed 3/6 (" << a << "!=5200)" << std::endl;
return false;
}
std::cout << "\tPassed 3/6...";
// 4. test increment (prefix)
++a;
if (a != large_number(5201)) {
std::cerr << "\tFailed 4/6 (" << a << "!=5201)" << std::endl;
return false;
}
std::cout << "\tPassed 4/6...";
// 5. test increment (postfix)
a++;
if (a != large_number(5202)) {
std::cerr << "\tFailed 5/6 (" << a << "!=5202)" << std::endl;
return false;
}
std::cout << "\tPassed 5/6...";
// 6. test addition with another large number
a = a + large_number("7000000000000000000000000000000");
if (a != large_number("7000000000000000000000000005202")) {
std::cerr << "\tFailed 6/6 (" << a
<< "!=7000000000000000000000000005202)" << std::endl;
return false;
}
std::cout << "\tPassed 6/6..." << std::endl;
return true;
}
/**
* add a digit at MSB to the large number
**/
void add_digit(unsigned int value) {
if (value > 9) {
std::cerr << "digit > 9!!\n";
exit(EXIT_FAILURE);
}
_digits.push_back(value);
}
/**
* Get number of digits in the number
**/
const size_t num_digits() const { return _digits.size(); }
/**
* operator over load to access the
* i^th digit conveniently and also
* assign value to it
**/
inline unsigned char &operator[](size_t n) { return this->_digits[n]; }
inline const unsigned char &operator[](size_t n) const {
return this->_digits[n];
}
/**
* operator overload to compare two numbers
**/
friend std::ostream &operator<<(std::ostream &out, const large_number &a) {
for (size_t i = a.num_digits(); i > 0; i--)
out << static_cast<int>(a[i - 1]);
return out;
}
/**
* operator overload to compare two numbers
**/
friend bool operator==(large_number const &a, large_number const &b) {
size_t N = a.num_digits();
if (N != b.num_digits())
return false;
for (size_t i = 0; i < N; i++)
if (a[i] != b[i])
return false;
return true;
}
/**
* operator overload to compare two numbers
**/
friend bool operator!=(large_number const &a, large_number const &b) {
return !(a == b);
}
/**
* operator overload to increment (prefix)
**/
large_number &operator++() {
(*this) += 1;
return *this;
}
/**
* operator overload to increment (postfix)
**/
large_number &operator++(int) {
static large_number tmp(_digits);
++(*this);
return tmp;
}
/**
* operator overload to add
**/
large_number &operator+=(large_number n) {
// if adding with another large_number
large_number *b = reinterpret_cast<large_number *>(&n);
const size_t max_L = std::max(this->num_digits(), b->num_digits());
unsigned int carry = 0;
size_t i;
for (i = 0; i < max_L || carry != 0; i++) {
if (i < b->num_digits())
carry += (*b)[i];
if (i < this->num_digits())
carry += (*this)[i];
if (i < this->num_digits())
(*this)[i] = carry % 10;
else
this->add_digit(carry % 10);
carry /= 10;
}
return *this;
}
large_number &operator+=(int n) { return (*this) += large_number(n); }
// large_number &operator+=(uint64_t n) { return (*this) += large_number(n);
// }
/**
* operator overload to perform addition
**/
template <class T>
friend large_number &operator+(const large_number &a, const T &b) {
static large_number c = a;
c += b;
return c;
}
/**
* assignment operator
**/
large_number &operator=(const large_number &b) {
this->_digits = b._digits;
return *this;
}
/**
* operator overload to increment
**/
template <class T>
large_number &operator*=(const T n) {
static_assert(std::is_integral<T>::value,
"Must be integer addition unsigned integer types.");
this->multiply(n);
return *this;
}
/**
* returns i^th digit as an ASCII character
**/
const char digit_char(size_t i) const {
return _digits[num_digits() - i - 1] + '0';
}
private:
/**
* multiply large number with another integer and
* store the result in the same large number
**/
template <class T>
void multiply(const T n) {
static_assert(std::is_integral<T>::value,
"Can only have integer types.");
// assert(!(std::is_signed<T>::value)); //, "Implemented only for
// unsigned integer types.");
size_t i;
uint64_t carry = 0, temp;
for (i = 0; i < this->num_digits(); i++) {
temp = (*this)[i] * n;
temp += carry;
if (temp < 10) {
carry = 0;
} else {
carry = temp / 10;
temp = temp % 10;
}
(*this)[i] = temp;
}
while (carry != 0) {
this->add_digit(carry % 10);
carry /= 10;
}
}
std::vector<unsigned char>
_digits; /**< where individual digits are stored */
};
#endif // MATH_LARGE_NUMBER_H_

View File

@@ -1,44 +1,59 @@
/*
* C++ Program to find the modular inverse using Fermat's Little Theorem.
* Fermat's Little Theorem state that => ϕ(m) = m-1, where m is a prime number.
*
* (a * x) ≡ 1 mod m.
* x ≡ (a^(-1)) mod m.
/**
* @file
* @brief C++ Program to find the modular inverse using [Fermat's Little
* Theorem](https://en.wikipedia.org/wiki/Fermat%27s_little_theorem)
*
* Fermat's Little Theorem state that \f[ϕ(m) = m-1\f]
* where \f$m\f$ is a prime number.
* \f{eqnarray*}{
* a \cdot x &≡& 1 \;\text{mod}\; m\\
* x &≡& a^{-1} \;\text{mod}\; m
* \f}
* Using Euler's theorem we can modify the equation.
*\f[
* a^{ϕ(m)} ≡ 1 \;\text{mod}\; m
* \f]
* (Where '^' denotes the exponent operator)
*
* (a^ϕ(m)) ≡ 1 mod m (Where '^' denotes the exponent operator)
* Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and 'm' must be relatively primes numbers.
* To apply Fermat's Little Theorem is necessary that 'm' must be a prime number.
* Generally in many competitive programming competitions 'm' is either 1000000007 (1e9+7) or 998244353.
* Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and
* 'm' must be relatively primes numbers. To apply Fermat's Little Theorem is
* necessary that 'm' must be a prime number. Generally in many competitive
* programming competitions 'm' is either 1000000007 (1e9+7) or 998244353.
*
* We considered m as large prime (1e9+7).
* (a^ϕ(m)) ≡ 1 mod m (Using Euler's Theorem)
* ϕ(m) = m-1 using Fermat's Little Theorem.
* (a^(m-1)) ≡ 1 mod m
* Now multiplying both side by (a^(-1)).
* (a^(m-1)) * (a^(-1)) ≡ (a^(-1)) mod m
* (a^(m-2)) ≡ (a^(-1)) mod m
* \f$a^{ϕ(m)} ≡ 1 \;\text{mod}\; m\f$ (Using Euler's Theorem)
* \f$ϕ(m) = m-1\f$ using Fermat's Little Theorem.
* \f$a^{m-1} ≡ 1 \;\text{mod}\; m\f$
* Now multiplying both side by \f$a^{-1}\f$.
* \f{eqnarray*}{
* a^{m-1} \cdot a^{-1} &≡& a^{-1} \;\text{mod}\; m\\
* a^{m-2} &≡& a^{-1} \;\text{mod}\; m
* \f}
*
* We will find the exponent using binary exponentiation. Such that the algorithm works in O(log(m)) time.
* We will find the exponent using binary exponentiation. Such that the
* algorithm works in \f$O(\log m)\f$ time.
*
* Example: -
* a = 3 and m = 7
* (a^(-1) mod m) is equivalent to (a^(m-2) mod m)
* (3^(5) mod 7) = (243 mod 7) = 5
* Hence, ( 3^(-1) mod 7 ) = 5
* or ( 3 * 5 ) mod 7 = 1 mod 7 (as a*(a^(-1)) = 1)
* Examples: -
* * a = 3 and m = 7
* * \f$a^{-1} \;\text{mod}\; m\f$ is equivalent to
* \f$a^{m-2} \;\text{mod}\; m\f$
* * \f$3^5 \;\text{mod}\; 7 = 243 \;\text{mod}\; 7 = 5\f$
* <br/>Hence, \f$3^{-1} \;\text{mod}\; 7 = 5\f$
* or \f$3 \times 5 \;\text{mod}\; 7 = 1 \;\text{mod}\; 7\f$
* (as \f$a\times a^{-1} = 1\f$)
*/
#include<iostream>
#include<vector>
#include <iostream>
#include <vector>
// Recursive function to calculate exponent in O(log(n)) using binary exponent.
/** Recursive function to calculate exponent in \f$O(\log n)\f$ using binary
* exponent.
*/
int64_t binExpo(int64_t a, int64_t b, int64_t m) {
a %= m;
int64_t res = 1;
while (b > 0) {
if (b%2) {
if (b % 2) {
res = res * a % m;
}
a = a * a % m;
@@ -48,13 +63,14 @@ int64_t binExpo(int64_t a, int64_t b, int64_t m) {
return res;
}
// Prime check in O(sqrt(m)) time.
/** Prime check in \f$O(\sqrt{m})\f$ time.
*/
bool isPrime(int64_t m) {
if (m <= 1) {
return false;
} else {
for (int i=2; i*i <= m; i++) {
if (m%i == 0) {
for (int64_t i = 2; i * i <= m; i++) {
if (m % i == 0) {
return false;
}
}
@@ -62,6 +78,9 @@ bool isPrime(int64_t m) {
return true;
}
/**
* Main function
*/
int main() {
int64_t a, m;
// Take input of a and m.
@@ -71,7 +90,7 @@ int main() {
std::cin >> a >> m;
if (isPrime(m)) {
std::cout << "The modular inverse of a with mod m is (a^(m-2)) : ";
std::cout << binExpo(a, m-2, m) << std::endl;
std::cout << binExpo(a, m - 2, m) << std::endl;
} else {
std::cout << "m must be a prime number.";
std::cout << std::endl;

View File

@@ -1,34 +1,39 @@
/// C++ Program to calculate number of divisors.
#include<iostream>
#include<vector>
/**
* @file
* @brief C++ Program to calculate number of divisors
*
* This algorithm use the prime factorization approach.
* Any number can be written in multiplication of its prime factors.
* Let N = P1^E1 * P2^E2 ... Pk^Ek
* Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1).
* Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents respectively.
* <br/>Let N = P1^E1 * P2^E2 ... Pk^Ek
* <br/>Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1).
* <br/>Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents
respectively.
*
* Example:-
* N = 36
* 36 = (3^2 * 2^2)
* number_of_positive_divisors(36) = (2+1) * (2+1) = 9.
* list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
* <br/>N = 36
* <br/>36 = (3^2 * 2^2)
* <br/>number_of_positive_divisors(36) = (2+1) * (2+1) = 9.
* <br/>list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
*
* Similarly if N is -36 at that time number of positive divisors remain same.
*
* Example:-
* N = -36
* -36 = -1 * (3^2 * 2^2)
* number_of_positive_divisors(-36) = (2+1) * (2+1) = 9.
* list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
* <br/>N = -36
* <br/>-36 = -1 * (3^2 * 2^2)
* <br/>number_of_positive_divisors(-36) = (2+1) * (2+1) = 9.
* <br/>list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
*
**/
#include <iostream>
#include <vector>
/**
* Algorithm
*/
int number_of_positive_divisors(int n) {
std::vector<int> prime_exponent_count;
for (int i=2; i*i <= n; i++) {
for (int i = 2; i * i <= n; i++) {
int prime_count = 0;
while (n % i == 0) {
prime_count += 1;
@@ -44,13 +49,16 @@ int number_of_positive_divisors(int n) {
int divisors_count = 1;
for (int i=0; i < prime_exponent_count.size(); i++) {
divisors_count = divisors_count * (prime_exponent_count[i]+1);
for (int i = 0; i < prime_exponent_count.size(); i++) {
divisors_count = divisors_count * (prime_exponent_count[i] + 1);
}
return divisors_count;
}
/**
* Main function
*/
int main() {
int n;
std::cin >> n;

View File

@@ -1,91 +1,90 @@
/**
* @file
* @brief Compute powers of large numbers
*/
#include <iostream>
using namespace std;
// Maximum number of digits in output
// x^n where 1 <= x, n <= 10000 and overflow may happen
/** Maximum number of digits in output
* \f$x^n\f$ where \f$1 <= x,\; n <= 10000\f$ and overflow may happen
*/
#define MAX 100000
// This function multiplies x
// with the number represented by res[].
// res_size is size of res[] or
// number of digits in the number
// represented by res[]. This function
// uses simple school mathematics
// for multiplication.
// This function may value of res_size
// and returns the new value of res_size
int multiply(int x, int res[], int res_size)
{
/** This function multiplies x
* with the number represented by res[].
* res_size is size of res[] or
* number of digits in the number
* represented by res[]. This function
* uses simple school mathematics
* for multiplication.
* This function may value of res_size
* and returns the new value of res_size
* @param x multiplicand
* @param res large number representation using array
* @param res_size number of digits in `res`
*/
int multiply(int x, int res[], int res_size) {
// Initialize carry
int carry = 0;
// Initialize carry
int carry = 0;
// One by one multiply n with
// individual digits of res[]
for (int i = 0; i < res_size; i++) {
int prod = res[i] * x + carry;
// One by one multiply n with
// individual digits of res[]
for (int i = 0; i < res_size; i++)
{
int prod = res[i] * x + carry;
// Store last digit of
// 'prod' in res[]
res[i] = prod % 10;
// Store last digit of
// 'prod' in res[]
res[i] = prod % 10;
// Put rest in carry
carry = prod / 10;
}
// Put rest in carry
carry = prod / 10;
}
// Put carry in res and
// increase result size
while (carry)
{
res[res_size] = carry % 10;
carry = carry / 10;
res_size++;
}
return res_size;
// Put carry in res and
// increase result size
while (carry) {
res[res_size] = carry % 10;
carry = carry / 10;
res_size++;
}
return res_size;
}
// This function finds
// power of a number x
void power(int x, int n)
{
/** This function finds power of a number x and print \f$x^n\f$
* @param x base
* @param n exponent
*/
void power(int x, int n) {
// printing value "1" for power = 0
if (n == 0) {
std::cout << "1";
return;
}
//printing value "1" for power = 0
if (n == 0)
{
cout << "1";
return;
}
int res[MAX];
int res_size = 0;
int temp = x;
int res[MAX];
int res_size = 0;
int temp = x;
// Initialize result
while (temp != 0) {
res[res_size++] = temp % 10;
temp = temp / 10;
}
// Initialize result
while (temp != 0)
{
res[res_size++] = temp % 10;
temp = temp / 10;
}
// Multiply x n times
// (x^n = x*x*x....n times)
for (int i = 2; i <= n; i++) res_size = multiply(x, res, res_size);
// Multiply x n times
// (x^n = x*x*x....n times)
for (int i = 2; i <= n; i++)
res_size = multiply(x, res, res_size);
cout << x << "^" << n << " = ";
for (int i = res_size - 1; i >= 0; i--)
cout << res[i];
std::cout << x << "^" << n << " = ";
for (int i = res_size - 1; i >= 0; i--) std::cout << res[i];
}
// Driver program
int main()
{
int exponent, base;
printf("Enter base ");
scanf("%id \n", &base);
printf("Enter exponent ");
scanf("%id", &exponent);
power(base, exponent);
return 0;
/** Main function */
int main() {
int exponent, base;
std::cout << "Enter base ";
std::cin >> base;
std::cout << "Enter exponent ";
std::cin >> exponent;
power(base, exponent);
return 0;
}

View File

@@ -1,80 +1,77 @@
/**
* @file
* @brief Prime factorization of positive integers
*/
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Declaring variables for maintaing prime numbers and to check whether a number is prime or not
/** Declaring variables for maintaing prime numbers and to check whether a
* number is prime or not
*/
bool isprime[1000006];
vector<int> prime_numbers;
vector<pair<int, int>> factors;
// Calculating prime number upto a given range
void SieveOfEratosthenes(int N)
{
/** list of prime numbers */
std::vector<int> prime_numbers;
/** list of prime factor-pairs */
std::vector<std::pair<int, int>> factors;
/** Calculating prime number upto a given range
*/
void SieveOfEratosthenes(int N) {
// initializes the array isprime
memset(isprime, true, sizeof isprime);
for (int i = 2; i <= N; i++)
{
if (isprime[i])
{
for (int j = 2 * i; j <= N; j += i)
isprime[j] = false;
for (int i = 2; i <= N; i++) {
if (isprime[i]) {
for (int j = 2 * i; j <= N; j += i) isprime[j] = false;
}
}
for (int i = 2; i <= N; i++)
{
for (int i = 2; i <= N; i++) {
if (isprime[i])
prime_numbers.push_back(i);
}
}
// Prime factorization of a number
void prime_factorization(int num)
{
/** Prime factorization of a number */
void prime_factorization(int num) {
int number = num;
for (int i = 0; prime_numbers[i] <= num; i++)
{
for (int i = 0; prime_numbers[i] <= num; i++) {
int count = 0;
// termination condition
if (number == 1)
{
if (number == 1) {
break;
}
while (number % prime_numbers[i] == 0)
{
while (number % prime_numbers[i] == 0) {
count++;
number = number / prime_numbers[i];
}
if (count)
factors.push_back(make_pair(prime_numbers[i], count));
factors.push_back(std::make_pair(prime_numbers[i], count));
}
}
/*
I added a simple UI.
*/
int main()
{
/** Main program */
int main() {
int num;
cout << "\t\tComputes the prime factorization\n\n";
cout << "Type in a number: ";
cin >> num;
std::cout << "\t\tComputes the prime factorization\n\n";
std::cout << "Type in a number: ";
std::cin >> num;
SieveOfEratosthenes(num);
prime_factorization(num);
// Prime factors with their powers in the given number in new line
for (auto it : factors)
{
cout << it.first << " " << it.second << endl;
for (auto it : factors) {
std::cout << it.first << " " << it.second << std::endl;
}
return 0;

View File

@@ -1,26 +1,33 @@
/**
* @file
* @brief Get list of prime numbers
* @see primes_up_to_billion.cpp sieve_of_eratosthenes.cpp
*/
#include <iostream>
#include <vector>
/** Generate an increasingly large number of primes
* and store in a list
*/
std::vector<int> primes(int max) {
max++;
std::vector<int> res;
std::vector<bool> numbers(max, false);
for (int i = 2; i < max; i++) {
if (!numbers[i]) {
for (int j = i; j < max; j += i)
numbers[j] = true;
for (int j = i; j < max; j += i) numbers[j] = true;
res.push_back(i);
}
}
return res;
}
/** main function */
int main() {
std::cout << "Calculate primes up to:\n>> ";
int n;
std::cin >> n;
std::vector<int> ans = primes(n);
for (int i = 0; i < ans.size(); i++)
std::cout << ans[i] << ' ';
for (int i = 0; i < ans.size(); i++) std::cout << ans[i] << ' ';
std::cout << std::endl;
}

View File

@@ -1,12 +1,19 @@
#include<iostream>
/**
* @file
* @brief Compute prime numbers upto 1 billion
* @see prime_numbers.cpp sieve_of_eratosthenes.cpp
*/
#include <cstring>
#include <iostream>
/** array to store the primes */
char prime[100000000];
/** Perform Sieve algorithm */
void Sieve(int64_t n) {
memset(prime, '1', sizeof(prime)); // intitize '1' to every index
prime[0] = '0'; // 0 is not prime
prime[1] = '0'; // 1 is not prime
prime[0] = '0'; // 0 is not prime
prime[1] = '0'; // 1 is not prime
for (int p = 2; p * p <= n; p++) {
if (prime[p] == '1') {
for (int i = p * p; i <= n; i += p)
@@ -15,7 +22,7 @@ void Sieve(int64_t n) {
}
}
/** Main function */
int main() {
Sieve(100000000);
int64_t n;
@@ -24,4 +31,6 @@ int main() {
std::cout << "YES\n";
else
std::cout << "NO\n";
return 0;
}

193
math/realtime_stats.cpp Normal file
View File

@@ -0,0 +1,193 @@
/**
* \file
* \brief Compute statistics for data entered in rreal-time
*
* This algorithm is really beneficial to compute statistics on data read in
* realtime. For example, devices reading biometrics data. The algorithm is
* simple enough to be easily implemented in an embedded system.
* \author [Krishna Vedala](https://github.com/kvedala)
*/
#include <cassert>
#include <cmath>
#include <iostream>
/**
* \namespace statistics
* \brief Statistical algorithms
*/
namespace statistics {
/**
* continuous mean and variance computance using
* first value as an approximation for the mean.
* If the first number is much far form the mean, the algorithm becomes very
* inaccurate to compute variance and standard deviation.
*/
template <typename T>
class stats_computer1 {
public:
/** Constructor
* \param[in] x new data sample
*/
void new_val(T x) {
if (n == 0)
K = x;
n++;
T tmp = x - K;
Ex += tmp;
Ex2 += tmp * tmp;
}
/** return sample mean computed till last sample */
double mean() const { return K + Ex / n; }
/** return data variance computed till last sample */
double variance() const { return (Ex2 - (Ex * Ex) / n) / (n - 1); }
/** return sample standard deviation computed till last sample */
double std() const { return std::sqrt(this->variance()); }
/** short-hand operator to read new sample from input stream
* \n e.g.: `std::cin >> stats1;`
*/
friend std::istream &operator>>(std::istream &input,
stats_computer1 &stat) {
T val;
input >> val;
stat.new_val(val);
return input;
}
private:
unsigned int n = 0;
double Ex, Ex2;
T K;
};
/**
* continuous mean and variance computance using
* Welford's algorithm (very accurate)
*/
template <typename T>
class stats_computer2 {
public:
/** Constructor
* \param[in] x new data sample
*/
void new_val(T x) {
n++;
double delta = x - mu;
mu += delta / n;
double delta2 = x - mu;
M += delta * delta2;
}
/** return sample mean computed till last sample */
double mean() const { return mu; }
/** return data variance computed till last sample */
double variance() const { return M / n; }
/** return sample standard deviation computed till last sample */
double std() const { return std::sqrt(this->variance()); }
/** short-hand operator to read new sample from input stream
* \n e.g.: `std::cin >> stats1;`
*/
friend std::istream &operator>>(std::istream &input,
stats_computer2 &stat) {
T val;
input >> val;
stat.new_val(val);
return input;
}
private:
unsigned int n = 0;
double mu = 0, var = 0, M = 0;
};
} // namespace statistics
using statistics::stats_computer1;
using statistics::stats_computer2;
/** Test the algorithm implementation
* \param[in] test_data array of data to test the algorithms
*/
void test_function(const float *test_data, const int number_of_samples) {
float mean = 0.f, variance = 0.f;
stats_computer1<float> stats01;
stats_computer2<float> stats02;
for (int i = 0; i < number_of_samples; i++) {
stats01.new_val(test_data[i]);
stats02.new_val(test_data[i]);
mean += test_data[i];
}
mean /= number_of_samples;
for (int i = 0; i < number_of_samples; i++) {
float temp = test_data[i] - mean;
variance += temp * temp;
}
variance /= number_of_samples;
std::cout << "<<<<<<<< Test Function >>>>>>>>" << std::endl
<< "Expected: Mean: " << mean << "\t Variance: " << variance
<< std::endl;
std::cout << "\tMethod 1:"
<< "\tMean: " << stats01.mean()
<< "\t Variance: " << stats01.variance()
<< "\t Std: " << stats01.std() << std::endl;
std::cout << "\tMethod 2:"
<< "\tMean: " << stats02.mean()
<< "\t Variance: " << stats02.variance()
<< "\t Std: " << stats02.std() << std::endl;
assert(std::abs(stats01.mean() - mean) < 0.01);
assert(std::abs(stats02.mean() - mean) < 0.01);
assert(std::abs(stats02.variance() - variance) < 0.01);
std::cout << "(Tests passed)" << std::endl;
}
/** Main function */
int main(int argc, char **argv) {
const float test_data1[] = {3, 4, 5, -1.4, -3.6, 1.9, 1.};
test_function(test_data1, sizeof(test_data1) / sizeof(test_data1[0]));
std::cout
<< "Enter data. Any non-numeric data will terminate the data input."
<< std::endl;
stats_computer1<float> stats1;
stats_computer2<float> stats2;
while (1) {
double val;
std::cout << "Enter number: ";
std::cin >> val;
// check for failure to read input. Happens for
// non-numeric data
if (std::cin.fail())
break;
stats1.new_val(val);
stats2.new_val(val);
std::cout << "\tMethod 1:"
<< "\tMean: " << stats1.mean()
<< "\t Variance: " << stats1.variance()
<< "\t Std: " << stats1.std() << std::endl;
std::cout << "\tMethod 2:"
<< "\tMean: " << stats2.mean()
<< "\t Variance: " << stats2.variance()
<< "\t Std: " << stats2.std() << std::endl;
}
return 0;
}

View File

@@ -1,69 +1,65 @@
/*
* Sieve of Eratosthenes is an algorithm to find the primes
/**
* @file
* @brief Get list of prime numbers using Sieve of Eratosthenes
* Sieve of Eratosthenes is an algorithm to find the primes
* that is between 2 to N (as defined in main).
*
* Time Complexity : O(N * log N)
* Space Complexity : O(N)
* Time Complexity : \f$O(N \cdot\log N)\f$
* <br/>Space Complexity : \f$O(N)\f$
*
* @see primes_up_to_billion.cpp prime_numbers.cpp
*/
#include <iostream>
using namespace std;
/** Maximum number of primes */
#define MAX 10000000
int isprime[MAX];
/** array to store the primes */
bool isprime[MAX];
/*
* This is the function that finds the primes and eliminates
/**
* This is the function that finds the primes and eliminates
* the multiples.
*/
void sieve(int N)
{
isprime[0] = 0;
isprime[1] = 0;
for (int i = 2; i <= N; i++)
{
if (isprime[i])
{
for (int j = i * 2; j <= N; j += i)
{
isprime[j] = 0;
void sieve(uint32_t N) {
isprime[0] = false;
isprime[1] = false;
for (uint32_t i = 2; i <= N; i++) {
if (isprime[i]) {
for (uint32_t j = (i << 1); j <= N; j += i) {
isprime[j] = false;
}
}
}
}
/*
/**
* This function prints out the primes to STDOUT
*/
void print(int N)
{
for (int i = 1; i <= N; i++)
{
if (isprime[i] == 1)
{
cout << i << ' ';
void print(uint32_t N) {
for (uint32_t i = 1; i <= N; i++) {
if (isprime[i]) {
std::cout << i << ' ';
}
}
cout << '\n';
std::cout << std::endl;
}
/*
* NOTE: This function is important for the
* initialization of the array.
/**
* Initialize the array
*/
void init()
{
for (int i = 1; i < MAX; i++)
{
isprime[i] = 1;
void init() {
for (uint32_t i = 1; i < MAX; i++) {
isprime[i] = true;
}
}
int main()
{
int N = 100;
/** main function */
int main() {
uint32_t N = 100;
init();
sieve(N);
print(N);
return 0;
}

View File

@@ -1,27 +1,35 @@
#include <iostream>
/**
* @file
* @brief Calculate the square root of any positive real number in \f$O(\log
* N)\f$ time, with precision fixed using [bisection
* method](https://en.wikipedia.org/wiki/Bisection_method) of root-finding.
*
* @see Can be implemented using faster and better algorithms like
* newton_raphson_method.cpp and false_position.cpp
*/
#include <cassert>
#include <iostream>
/* Calculate the square root of any
number in O(logn) time,
with precision fixed */
double Sqrt(double x) {
if ( x > 0 && x < 1 ) {
return 1/Sqrt(1/x);
/** Bisection method implemented for the function \f$x^2-a=0\f$
* whose roots are \f$\pm\sqrt{a}\f$ and only the positive root is returned.
*/
double Sqrt(double a) {
if (a > 0 && a < 1) {
return 1 / Sqrt(1 / a);
}
double l = 0, r = x;
/* Epsilon is the precision.
A great precision is
double l = 0, r = a;
/* Epsilon is the precision.
A great precision is
between 1e-7 and 1e-12.
double epsilon = 1e-12;
*/
double epsilon = 1e-12;
while ( l <= r ) {
while (l <= r) {
double mid = (l + r) / 2;
if ( mid * mid > x ) {
if (mid * mid > a) {
r = mid;
} else {
if ( x - mid * mid < epsilon ) {
if (a - mid * mid < epsilon) {
return mid;
}
l = mid;
@@ -29,11 +37,13 @@ double Sqrt(double x) {
}
return -1;
}
/** main function */
int main() {
double n{};
std::cin >> n;
assert(n >= 0);
// Change this line for a better precision
std::cout.precision(12);
std::cout << std::fixed << Sqrt(n);
double n{};
std::cin >> n;
assert(n >= 0);
// Change this line for a better precision
std::cout.precision(12);
std::cout << std::fixed << Sqrt(n);
}

89
math/string_fibonacci.cpp Normal file
View File

@@ -0,0 +1,89 @@
/**
* @file
* @brief This Programme returns the Nth fibonacci as a string.
*
* The method used is manual addition with carry and placing it in a string
* which is called string addition This makes it have no bounds or limits
*
* @see fibonacci_large.cpp, fibonacci_fast.cpp, fibonacci.cpp
*/
#include <iostream>
#ifdef _MSC_VER
#include <string> // use this for MS Visual C
#else
#include <cstring> // otherwise
#endif
/**
* function to add two string numbers
* \param [in] a first number in string to add
* \param [in] b second number in string to add
* \returns sum as a std::string
*/
std::string add(std::string a, std::string b) {
std::string temp = "";
// carry flag
int carry = 0;
// fills up with zeros
while (a.length() < b.length()) {
a = "0" + a;
}
// fills up with zeros
while (b.length() < a.length()) {
b = "0" + b;
}
// adds the numbers a and b
for (int i = a.length() - 1; i >= 0; i--) {
char val = static_cast<char>(((a[i] - 48) + (b[i] - 48)) + 48 + carry);
if (val > 57) {
carry = 1;
val -= 10;
} else {
carry = 0;
}
temp = val + temp;
}
// processes the carry flag
if (carry == 1) {
temp = "1" + temp;
}
// removes leading zeros.
while (temp[0] == '0' && temp.length() > 1) {
temp = temp.substr(1);
}
return temp;
}
/** Fibonacci iterator
* \param [in] n n^th Fibonacci number
*/
void fib_Accurate(uint64_t n) {
std::string tmp = "";
std::string fibMinus1 = "1";
std::string fibMinus2 = "0";
for (uint64_t i = 0; i < n; i++) {
tmp = add(fibMinus1, fibMinus2);
fibMinus2 = fibMinus1;
fibMinus1 = tmp;
}
std::cout << fibMinus2;
}
/** main function */
int main() {
int n;
std::cout << "Enter whatever number N you want to find the fibonacci of\n";
std::cin >> n;
std::cout << n << " th Fibonacci is \n";
fib_Accurate(n);
return 0;
}