symbolic4
math_foundation.c
Go to the documentation of this file.
1 
2 /*
3 
4  Copyright (c) 2019 Hannes Eberhard
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  SOFTWARE.
23 
24  */
25 
26 #include "symbolic4.h"
27 
28 uintmax_t min(uintmax_t a, uintmax_t b) {
29  return (a < b) ? a : b;
30 }
31 
32 uintmax_t max(uintmax_t a, uintmax_t b) {
33  return (a > b) ? a : b;
34 }
35 
36 /**
37 
38  @brief Computes the GCD of two integers
39 
40  @details
41  This function computes the greatest common divisor of two integers
42  using the iterative Euclidean algorithm.
43 
44  @param[in] a The first integer.
45  @param[in] b The second integer.
46 
47  @return
48  - The greatest common divisor.
49 
50  */
51 uintmax_t euclidean_gcd(uintmax_t a, uintmax_t b) {
52 
53  uintmax_t t;
54 
55  while (b != 0) {
56  t = b;
57  b = a % b;
58  a = t;
59  }
60 
61  return a;
62 
63 }
64 
65 expression* prime_factors(uintmax_t source) {
66 
67  uintmax_t factor = 2;
69 
70  if (source % factor == 0) {
72  new_literal(1, factor, 1),
73  new_literal(1, 0, 1)));
74  }
75 
76  while (source % factor == 0) {
77  factors->children[factors->child_count - 1]->children[1]->value.numeric.numerator++;
78  source /= factor;
79  }
80 
81  for (factor = 3; factor <= sqrt(source); factor += 2) {
82 
83  if (source % factor == 0) {
85  new_literal(1, factor, 1),
86  new_literal(1, 0, 1)));
87  }
88 
89  while (source % factor == 0) {
90  factors->children[factors->child_count - 1]->children[1]->value.numeric.numerator++;
91  source /= factor;
92  }
93 
94  }
95 
96  if (source > 2) {
98  new_literal(1, source, 1),
99  new_literal(1, 1, 1)));
100  }
101 
102  return factors;
103 
104 }
105 
106 uintmax_t* binomial_coefficients(uint8_t n) {
107 
108  uint8_t i, j;
109  uintmax_t* coefficients = smart_alloc(n + 1, sizeof(uintmax_t));
110  memset(coefficients, 0, (n + 1) * sizeof(uintmax_t));
111 
112  coefficients[0] = 1;
113 
114  for (i = 1; i <= n; i++) {
115  for (j = min(i, n); j > 0; j--) {
116  coefficients[j] = coefficients[j] + coefficients[j - 1];
117  }
118  }
119 
120  return coefficients;
121 
122 }
123 
124 uint8_t addition(uintmax_t* result, uintmax_t a, uintmax_t b) {
125  if (((double) a + (double) b) < uintmax_max_value()) {
126  *result = a + b;
127  return RETS_SUCCESS;
128  } else {
129  return RETS_ERROR;
130  }
131 }
132 
133 uint8_t multiplication(uintmax_t* result, uintmax_t a, uintmax_t b) {
134  if (((double) a * (double) b) < uintmax_max_value()) {
135  *result = a * b;
136  return RETS_SUCCESS;
137  } else {
138  return RETS_ERROR;
139  }
140 }
141 
142 uint8_t int_power(uintmax_t* result, uintmax_t base, uintmax_t exponent) {
143  *result = 1;
144  if (pow(base, exponent) < uintmax_max_value()) {
145  for ( ; exponent > 0; exponent--) *result *= base;
146  return RETS_SUCCESS;
147  } else {
148  return RETS_ERROR;
149  }
150 }
151 
152 void int_root(uintmax_t* factor, uintmax_t* remainder, uintmax_t base, uintmax_t degree) {
153 
154  uint8_t i;
155  uintmax_t temp_result;
156  expression* factors = prime_factors(base);
157 
158  for (i = 0; i < factors->child_count; i++) {
159  while (factors->children[i]->children[1]->value.numeric.numerator >= degree) {
160  factors->children[i]->children[1]->value.numeric.numerator -= degree;
161  *factor *= factors->children[i]->children[0]->value.numeric.numerator;
162  int_power(&temp_result, factors->children[i]->children[0]->value.numeric.numerator, degree);
163  *remainder /= temp_result;
164  }
165  }
166 
167  free_expression(factors, false);
168 
169 }
EXPI_LIST
Definition: expression.h:90
int_power
uint8_t int_power(uintmax_t *result, uintmax_t base, uintmax_t exponent)
Definition: math_foundation.c:142
symbolic4.h
expression
Definition: expression.h:112
prime_factors
expression * prime_factors(uintmax_t source)
Definition: math_foundation.c:65
EXPT_STRUCTURE
Definition: expression.h:36
euclidean_gcd
uintmax_t euclidean_gcd(uintmax_t a, uintmax_t b)
Computes the GCD of two integers.
Definition: math_foundation.c:51
expression::value
union expression::@0 value
RETS_SUCCESS
Definition: foundation.h:67
uintmax_max_value
double uintmax_max_value(void)
Definition: foundation.c:188
RETS_ERROR
Definition: foundation.h:66
free_expression
void free_expression(expression *source, bool persistent)
Definition: expression.c:315
binomial_coefficients
uintmax_t * binomial_coefficients(uint8_t n)
Definition: math_foundation.c:106
int_root
void int_root(uintmax_t *factor, uintmax_t *remainder, uintmax_t base, uintmax_t degree)
Definition: math_foundation.c:152
multiplication
uint8_t multiplication(uintmax_t *result, uintmax_t a, uintmax_t b)
Definition: math_foundation.c:133
expression::numeric
numeric_value numeric
Definition: expression.h:129
max
uintmax_t max(uintmax_t a, uintmax_t b)
Definition: math_foundation.c:32
append_child
void append_child(expression *parent, expression *child)
Appends a child to an expression.
Definition: expression.c:383
new_expression
expression * new_expression(expression_type type, expression_identifier identifier, uint8_t child_count,...)
Allocates and initializes a new expression with the arguments provided.
Definition: expression.c:183
addition
uint8_t addition(uintmax_t *result, uintmax_t a, uintmax_t b)
Definition: math_foundation.c:124
min
uintmax_t min(uintmax_t a, uintmax_t b)
Definition: math_foundation.c:28
new_literal
expression * new_literal(int8_t sign, uintmax_t numerator, uintmax_t denominator)
Allocates and initializes a new literal expression.
Definition: expression.c:225
expression::child_count
uint8_t child_count
Definition: expression.h:119
expression::children
struct expression ** children
Definition: expression.h:124
numeric_value::numerator
uintmax_t numerator
Definition: expression.h:108
smart_alloc
void * smart_alloc(uint8_t length, size_t size)
Allocates and keeps track of memory.
Definition: foundation.c:59