Skip to content

Commit f56a069

Browse files
committed
0.0.2.4
Optimized GLpoint implementation
1 parent 176c635 commit f56a069

4 files changed

Lines changed: 62 additions & 29 deletions

File tree

CHANGELOG.md

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,31 @@
66

77
bench_1 Result:
88

9-
| time | RL | GL |
10-
| ---- | ----------- | ----------- |
11-
| 1+e2 | 0.0482 ms | * |
12-
| 1+e3 | 5.6009 ms | 0.9822 ms |
13-
| 1+e4 | 605.5952 ms | 5.2982 ms |
14-
| 1+e5 | * | 104.1740 ms |
15-
| 1+e6 | * | 667.7444 ms |
9+
| time | GL | RL | GLpoint | RLpoint |
10+
| ---- | ----------- | ----------- | ----------- | ---------- |
11+
| 1+e2 | * | 0.0482 ms | * | 0.0099 ms |
12+
| 1+e3 | 0.9822 ms | 5.6009 ms | 0.0083 ms | 0.0899 ms |
13+
| 1+e4 | 5.2982 ms | 605.5952 ms | 0.0721 ms | 1.0599 ms |
14+
| 1+e5 | 104.1740 ms | * | 1.5568 ms | 9.6303 ms |
15+
| 1+e6 | 667.7444 ms | * | 10.0608 ms | 93.9401 ms |
16+
17+
18+
## 0.0.2.4: Optimized GLpoint implementation
19+
20+
- GLpoint
21+
- On-the-fly Coefficient Calculation
22+
- Efficient Memory Access
23+
- Precomputed Constants
24+
- GLcoeffs optimization
25+
26+
27+
bench_1 Result and comparison to original differint package (1.0.0):
28+
29+
| time | 0.0.2.3 | 0.0.2.4 | differint |
30+
| ---- | ----------- | ----------- | ----------- |
31+
| 1+e2 | * | * | * |
32+
| 1+e3 | 0.0083 ms | 0.0099 ms | 0.4213 ms |
33+
| 1+e4 | 0.0721 ms | 0.0243 ms | 3.8376 ms |
34+
| 1+e5 | 1.5568 ms | 0.1885 ms | 36.3030 ms |
35+
| 1+e6 | 10.0608 ms | 3.9995 ms | 385.9205 ms |
36+
| 1+e7 | * | 41.2 ms | * |

README.MD

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
- **Only Windows Support for now!**
2+
13
# differintC
24

35
`differintC` is a high-performance C++ library with Python bindings for computing fractional differintegrals (derivatives and integrals of arbitrary real order) using numerical methods.
46

5-
This package implements optimized versions of the Riemann–Liouville and Grünwald–Letnikov (GL) fractional differintegral operators, inspired by the original [DifferInt project](https://placeholder-link-to-original-differint-project).
7+
This package implements optimized versions of the Riemann–Liouville and Grünwald–Letnikov (GL) fractional differintegral operators, inspired by the original [DifferInt project](https://github.com/differint/differint).
68

79
> ⚙️ Built with modern C++17 and exposed to Python via `pybind11`, this library is significantly faster than pure-Python equivalents, especially for large arrays and high-precision needs.
810
@@ -14,13 +16,6 @@ This package implements optimized versions of the Riemann–Liouville and Grünw
1416
pip install differintC
1517
````
1618

17-
To build from source:
18-
19-
```bash
20-
git clone https://github.com/your-username/differintC-project.git
21-
cd differintC-project
22-
pip install .
23-
```
2419

2520
---
2621

differintC/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.2.3" # <-- ANY PEP 440 version string allowed
1+
__version__ = "0.0.2.4" # <-- ANY PEP 440 version string allowed

src/differint.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,17 @@ std::vector<T> RL(T alpha,
131131
// Compute GL coefficients up to order n
132132
template <typename T>
133133
std::vector<T> GLcoeffs(T alpha, std::size_t n) {
134-
// b[0] = 1
135-
std::vector<T> b(n + 1, T(1));
134+
std::vector<T> b;
135+
b.reserve(n + 1); // Preallocate memory
136+
b.push_back(T(1)); // b0 = 1
137+
136138
for (std::size_t j = 1; j <= n; ++j) {
137-
b[j] = b[j - 1] * (static_cast<T>(-alpha) + static_cast<T>(j - 1))
138-
/ static_cast<T>(j);
139+
T j_t = static_cast<T>(j);
140+
b.push_back(b.back() * (j_t - 1 - alpha) / j_t);
139141
}
140142
return b;
141143
}
142144

143-
144145
// GL at a single point (endpoint)
145146
template <typename T>
146147
T GLpoint(T alpha,
@@ -158,15 +159,31 @@ T GLpoint(T alpha,
158159
if (f_vals.size() != num_points) {
159160
throw std::invalid_argument("f_vals size must equal num_points");
160161
}
161-
T step = (domain_end - domain_start) / static_cast<T>(num_points - 1);
162-
// Compute coefficients for k = num_points - 1
163-
std::size_t k = num_points - 1;
164-
auto b = GLcoeffs(alpha, k);
165-
T acc = T(0);
166-
for (std::size_t j = 0; j <= k; ++j) {
167-
acc += b[j] * f_vals[k - j];
162+
163+
const T step = (domain_end - domain_start) / static_cast<T>(num_points - 1);
164+
const T step_power = std::pow(step, -alpha);
165+
const std::size_t k = num_points - 1;
166+
167+
T acc = 0;
168+
T c_val = 1.0; // Initialize to b0 = 1
169+
const T* f_ptr = f_vals.data() + k; // Pointer to last element (f_vals[k])
170+
171+
for (std::size_t j_index = 0; j_index <= k; ++j_index) {
172+
// Add current term: c_val * f_vals[k - j_index]
173+
acc += c_val * (*f_ptr);
174+
175+
// Prepare for next iteration (skip for last element)
176+
if (j_index < k) {
177+
// Update coefficient using recurrence relation:
178+
// c_{j+1} = c_j * ( -alpha + j_index ) / (j_index + 1)
179+
c_val *= ( -alpha + static_cast<T>(j_index) ) / static_cast<T>(j_index + 1);
180+
}
181+
182+
// Move pointer backward through f_vals
183+
--f_ptr;
168184
}
169-
return std::pow(step, -alpha) * acc;
185+
186+
return step_power * acc;
170187
}
171188

172189
// GL over entire grid

0 commit comments

Comments
 (0)