Skip to content

Commit b8148f3

Browse files
committed
add SmileRoots
1 parent 4e8aa33 commit b8148f3

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

source/mir/numeric.d

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,63 @@ version(mir_test) @safe unittest
14151415
}
14161416
}
14171417

1418+
/++
1419+
A set of one or two smile roots.
1420+
1421+
Because we assume that volatility smile is convex the equantion above can have no more then two roots.
1422+
1423+
The `left` and `right` members are equal if the smile has only one root.
1424+
+/
1425+
struct SmileRoots(T)
1426+
if (__traits(isFloating, T))
1427+
{
1428+
import mir.small_array: SmallArray;
1429+
1430+
///
1431+
T left;
1432+
///
1433+
T right;
1434+
1435+
@safe pure nothrow @nogc:
1436+
1437+
///
1438+
this(T value)
1439+
{
1440+
left = right = value;
1441+
}
1442+
1443+
///
1444+
this(T left, T right)
1445+
{
1446+
this.left = left;
1447+
this.right = right;
1448+
}
1449+
1450+
///
1451+
this(SmallArray!(T, 2) array)
1452+
{
1453+
if (array.length == 2)
1454+
this(array[0], array[1]);
1455+
else
1456+
if (array.length == 1)
1457+
this(array[0]);
1458+
else
1459+
this(T.nan, T.nan);
1460+
}
1461+
1462+
///
1463+
inout(T)[] opIndex() @trusted inout
1464+
{
1465+
return (&left)[0 .. 2];
1466+
}
1467+
1468+
///
1469+
size_t count() const
1470+
{
1471+
return 1 + (left != right);
1472+
}
1473+
}
1474+
14181475
/++
14191476
+/
14201477
struct FindSmileRootsResult(T)
@@ -1476,6 +1533,14 @@ struct FindSmileRootsResult(T)
14761533
ret.append(rightResult.get.x);
14771534
return ret;
14781535
}
1536+
1537+
/++
1538+
Returns: $(LREF SmileRoots).
1539+
+/
1540+
SmileRoots!double smileRoots()()
1541+
{
1542+
return typeof(return)(roots);
1543+
}
14791544
}
14801545

14811546
/++
@@ -1537,6 +1602,8 @@ unittest
15371602
assert(result.roots.length == 2);
15381603
assert(result.roots[0].approxEqual(-1));
15391604
assert(result.roots[1].approxEqual(+1));
1605+
assert(result.smileRoots.left.approxEqual(-1));
1606+
assert(result.smileRoots.right.approxEqual(+1));
15401607
assert(result.leftResult);
15411608
assert(result.rightResult);
15421609
assert(result.localMinResult);
@@ -1552,6 +1619,8 @@ unittest
15521619
auto result = findSmileRoots!(x => x ^^ 2 - 1)(0.5, 10.0);
15531620
assert(result.roots.length == 1);
15541621
assert(result.roots[0].approxEqual(+1));
1622+
assert(result.smileRoots.left.approxEqual(+1));
1623+
assert(result.smileRoots.right.approxEqual(+1));
15551624
assert(!result.leftResult);
15561625
assert(result.rightResult);
15571626
}
@@ -1562,6 +1631,8 @@ unittest
15621631
auto result = findSmileRoots!(x => x ^^ 2 - 1)(-10.0, -0.5);
15631632
assert(result.roots.length == 1);
15641633
assert(result.roots[0].approxEqual(-1));
1634+
assert(result.smileRoots.left.approxEqual(-1));
1635+
assert(result.smileRoots.right.approxEqual(-1));
15651636
assert(result.leftResult);
15661637
assert(!result.rightResult);
15671638
}

0 commit comments

Comments
 (0)