@@ -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+/
14201477struct 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