Skip to content

Commit 619e7f5

Browse files
authored
Add polynomial (#216)
* add polynomial * fix docs
1 parent 8dde2e0 commit 619e7f5

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

doc/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ ARTWORK_DIR=$(DOC_SOURCE_DIR)/artwork
2828
# packages and their modules.
2929
MIR_PACKAGES = mir mir/rc mir/ndslice mir/ndslice/connect mir/math mir/math/func mir/array mir/interpolate mir/graph mir/combinatorics mir/container mir/algorithm
3030

31-
PACKAGE_mir = range series numeric type_info small_string small_array
31+
PACKAGE_mir = range series numeric type_info small_string small_array polynomial
3232

3333
PACKAGE_mir_algorithm = iteration setops
3434
PACKAGE_mir_array = allocation

index.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ $(BOOKTABLE ,
2020
$(TR $(TDNW $(MREF mir,math,numeric)) $(TD Simple numeric algorithms))
2121
$(TR $(TDNW $(MREF mir,math,sum)★) $(TD Various precise summation algorithms))
2222
$(TR $(TDNW $(MREF mir,math,constant)) $(TD Math constants))
23+
$(TR $(TDNW $(MREF mir,polynomial)) $(TD Polynomial ref-counted structure))
2324
$(LEADINGROW Reference counting)
2425
$(TR $(TDNW $(MREF mir,rc,array)) $(TD Thread safe reference count array and the iterator to adopt it to ndslice.))
2526
$(TR $(TDNW $(MREF mir,rc,ptr)) $(TD Thread safe reference count pointer for strucs and objects.))

source/mir/polynomial.d

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/++
2+
Polynomial ref-counted structure.
3+
4+
License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
5+
Authors: Ilya Yaroshenko
6+
+/
7+
module mir.polynomial;
8+
9+
import mir.math.common: optmath;
10+
import mir.rc.array;
11+
12+
@optmath:
13+
14+
/++
15+
Polynomial callable ref-counted structure.
16+
+/
17+
struct Polynomial(F)
18+
{
19+
///
20+
RCArray!(const F) coefficients;
21+
22+
/++
23+
Params:
24+
coefficients = coefficients `c[i]` for polynomial function `f(x)=c[0]+c[1]*x^^1+...+c[n]*x^^n`
25+
+/
26+
this(RCArray!(const F) coefficients)
27+
{
28+
import core.lifetime: move;
29+
this.coefficients = coefficients.move;
30+
}
31+
32+
/++
33+
Params:
34+
derivative = derivative order
35+
+/
36+
template opCall(uint derivative = 0)
37+
{
38+
/++
39+
Params:
40+
x = `x` point
41+
+/
42+
@optmath typeof(F.init * X.init * 1f + F.init) opCall(X)(in X x)
43+
{
44+
import mir.internal.utility: Iota;
45+
auto ret = cast(typeof(return))0;
46+
if (coefficients)
47+
{
48+
ptrdiff_t i = coefficients.length - 1;
49+
auto c = cast()coefficients[i];
50+
static foreach (d; Iota!derivative)
51+
c *= i - d;
52+
ret = cast(typeof(return)) c;
53+
while (--i >= derivative)
54+
{
55+
c = cast()coefficients[i];
56+
static foreach (d; Iota!derivative)
57+
c *= i - d;
58+
ret *= x;
59+
ret += c;
60+
}
61+
}
62+
return ret;
63+
}
64+
}
65+
}
66+
67+
/// ditto
68+
Polynomial!F polynomial(F)(RCArray!(const F) coefficients)
69+
{
70+
import core.lifetime: move;
71+
return typeof(return)(coefficients.move);
72+
}
73+
74+
///
75+
version (mir_test) @safe pure nothrow @nogc unittest
76+
{
77+
import mir.math.common: approxEqual;
78+
import mir.rc.array;
79+
auto a = rcarray!(const double)(3.0, 4.5, 1.9, 2);
80+
auto p = a.polynomial;
81+
82+
alias f = (x) => 3.0 + 4.5 * x^^1 + 1.9 * x^^2 + 2 * x^^3;
83+
alias df = (x) => 4.5 + 2 * 1.9 * x^^1 + 3 * 2 * x^^2;
84+
alias d2f = (x) => 2 * 1.9 + 6 * 2 * x^^1;
85+
86+
assert(p(3.3).approxEqual(f(3.3)));
87+
assert(p(7.2).approxEqual(f(7.2)));
88+
89+
assert(p.opCall!1(3.3).approxEqual(df(3.3)));
90+
assert(p.opCall!1(7.2).approxEqual(df(7.2)));
91+
92+
assert(p.opCall!2(3.3).approxEqual(d2f(3.3)));
93+
assert(p.opCall!2(7.2).approxEqual(d2f(7.2)));
94+
}

0 commit comments

Comments
 (0)